How to determine w/o conversions that a given floating constant can be represented?
Sample code:
#define FLOATING_CONSTANT1 2147483647.0f
#define FLOATING_CONSTANT2 2147483520.0f
bool b1 = FLOATING_CONSTANT_CAN_BE_REPRESENTED( FLOATING_CONSTANT1 ); // false
bool b2 = FLOATING_CONSTANT_CAN_BE_REPRESENTED( FLOATING_CONSTANT2 ); // true
"w/o conversions" seems to be an unnecessary restrictive requirement, but something to get OP started and a test harness for others.
#define str(s) #s
#define xstr(s) str(s)
#define FLOATING_CONSTANT_CAN_BE_REPRESENTED(fc1) float_const_test(xstr(fc1), fc1)
bool float_const_test(const char *s, float f1) {
printf("<%s> %g\n", s, f1);
char *endptr;
errno = 0;
double d2 = strtod(s, &endptr);
if (s == endptr) return false;
if (strcmp(endptr, "f") && strcmp(endptr, "F")) return false;
if (f1 != d2) return false;
// Note a 100% here, the string may have rounded to a double.
return true;
}
int main(void) {
puts("Good");
printf("%d\n", FLOATING_CONSTANT_CAN_BE_REPRESENTED(1.5f));
printf("%d\n", FLOATING_CONSTANT_CAN_BE_REPRESENTED(0x1.5p0f));
puts("\nBad");
printf("%d\n", FLOATING_CONSTANT_CAN_BE_REPRESENTED(1.23f));
printf("%d\n", FLOATING_CONSTANT_CAN_BE_REPRESENTED(1.23e40f));
}
Output
Good
<1.5f> 1.5
1
<0x1.5p0f> 1.3125
1
Bad
<1.23f> 1.23
0
<1.23e40f> inf
0
Notes:
If the fractional portion of a FP constant does not end in 5
or 0
, it cannot be exactly converted to a float/double
.
When exact FP constants are needed, the first step is to consider hexadecimal-floating-constant such a 0x1.23CDp12f