#include #include #include #include #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"); } }