test.c
text/plain
Filename: test.c
Type: text/plain
Part: 0
#include <stdio.h>
#include <stdint.h>
#include <math.h>
#include <float.h>
#define PG_INT64_MAX INT64_MAX
#define PG_INT64_MIN INT64_MIN
/*
* Check if a double value can be casted into int64.
*
* This macro is assuming that FLT_RADIX == 2 so that the * 2.0 trick works,
* PG_INT64_MAX is so below DBL_MAX that the doubled value can be represented
* in double and DBL_MANT_DIG is equal or smaller than DBL_MAX_EXP so that
* ceil() returns expected result.
*/
#define MIN_DOUBLE_OVER_INT64_MAX (2.0 * (double) (PG_INT64_MAX / 2 + 1))
#define MAX_DOUBLE_UNDER_INT64_MIN (2.0 * (double) (PG_INT64_MIN / 2 - 1))
#if -PG_INT64_MAX != PG_INT64_MIN
#define IS_DOUBLE_SAFE_IN_INT64(x) \
((x) < MIN_DOUBLE_OVER_INT64_MAX && ceil(x) >= (double) PG_INT64_MIN)
#else
#define IS_DOUBLE_SAFE_IN_INT64(x) \
((x) < MIN_DOUBLE_OVER_INT64_MAX && (x) > MAX_DOUBLE_UNDER_INT64_MIN)
#endif
int main()
{
double values[] =
{
-pow(2, 63) - 1025,
-pow(2, 63),
pow(2, 63) - 1024,
pow(2, 63),
INFINITY,
-INFINITY,
NAN
};
for (int i = 0; i < sizeof(values) / sizeof(values[0]); i++)
{
double value = values[i];
printf("value == %lf, Overflow = %s\n", value,
!IS_DOUBLE_SAFE_IN_INT64(value) ? "true" : "false");
}
}