Before this afternoon, I thought that a check like this for a double 'd': d == floor (d) && d >= LONG_MIN && d <= LONG_MAX was sufficient to determine whether converting 'd' to 'long' would yield a 'long' with the same value as 'd'.
Now I realize that this is wrong. In particular, take a look at the following program: #include <limits.h> #include <stdio.h> int main (void) { long i = LONG_MAX; double d = i; long j = d; printf ("%ld, %f, %ld\n", i, d, j); return 0; } On my system, this prints: 9223372036854775807, 9223372036854775808.000000, -9223372036854775808 In other words, LONG_MAX gets rounded up to 2**63 when it's converted to 'double', which makes sense because 'double' only has 53 bits of precision, but this also means that 'd <= LONG_MAX' and still doesn't fit in 'long', as one can see from it getting converted to a wrong answer (-2**63 instead of 2**63) when converted back to 'long'. And of course any answer is OK there, since this out-of-range conversion yields undefined behavior. Can anyone suggest a correct way to check whether a 'double' is in the range of 'long'? One workaround would be to check for the range of 'int' (or int32_t, I guess really), since there's not going to be any loss of precision converting INT(32)_MAX to 'double'. But I'd rather support a wider range in the code I'm working on. Thanks, Ben.