“无转换”似乎是不必要的限制性要求,但可以让 OP 开始并为其他人提供测试工具。
#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));
}
输出
Good
<1.5f> 1.5
1
<0x1.5p0f> 1.3125
1
Bad
<1.23f> 1.23
0
<1.23e40f> inf
0
笔记:
如果 FP 常量的小数部分不以5
or结尾0
,则它不能完全转换为 a float/double
。
当需要精确的FP 常数时,第一步是考虑hexadecimal-floating-constant这样的0x1.23CDp12f