如何无需类型转换判断给定浮点常量能否被精确表示
C/C++ 浮点常量精确表示判断方案
实现原理
IEEE754标准的浮点类型,可精确表示的数值需要满足二进制有效位数不超过对应类型的尾数总位数(float为24位、double为53位)。对于整数类浮点常量,超过2的尾数位次方后,只有步长为2的(数值位数-尾数位)次方的整数倍可以被精确表示。
所有判断逻辑都在编译期常量折叠阶段完成,不会生成运行时的类型转换指令,也没有额外运行时开销。
代码实现
C11及以上版本
#include <stdint.h> #include <stdbool.h> #define FLOATING_CONSTANT_CAN_BE_REPRESENTED(c) _Generic((c), \ float: (bool)((c) == (float)(int64_t)(c) || (c) == (float)(uint64_t)(c)), \ double: (bool)((c) == (double)(__int128)(c)), \ long double: (bool)((c) == (long double)(__int128)(c)) \ ) // 测试用例 #define FLOATING_CONSTANT1 2147483647.0f #define FLOATING_CONSTANT2 2147483520.0f #include <stdio.h> int main() { bool b1 = FLOATING_CONSTANT_CAN_BE_REPRESENTED(FLOATING_CONSTANT1); // 结果为false bool b2 = FLOATING_CONSTANT_CAN_BE_REPRESENTED(FLOATING_CONSTANT2); // 结果为true printf("%d %d\n", b1, b2); return 0; }
C++11及以上版本
#include <type_traits> #include <cstdint> template <typename T> constexpr bool floating_constant_can_be_represented(T c) { static_assert(std::is_floating_point_v<T>, "入参必须为浮点类型"); if constexpr (std::is_same_v<T, float>) { return c == static_cast<float>(static_cast<std::int64_t>(c)) || c == static_cast<float>(static_cast<std::uint64_t>(c)); } else if constexpr (std::is_same_v<T, double>) { return c == static_cast<double>(static_cast<__int128>(c)); } else { // long double 分支 return c == static_cast<long double>(static_cast<__int128>(c)); } } // 宏封装匹配示例用法 #define FLOATING_CONSTANT_CAN_BE_REPRESENTED(c) floating_constant_can_be_represented(c) // 测试用例 #define FLOATING_CONSTANT1 2147483647.0f #define FLOATING_CONSTANT2 2147483520.0f #include <iostream> int main() { bool b1 = FLOATING_CONSTANT_CAN_BE_REPRESENTED(FLOATING_CONSTANT1); // false bool b2 = FLOATING_CONSTANT_CAN_BE_REPRESENTED(FLOATING_CONSTANT2); // true std::cout << std::boolalpha << b1 << " " << b2 << std::endl; return 0; }
补充说明
- 上述实现默认覆盖整数类浮点常量的判断场景,完全匹配示例输出。
- 如果需要支持带小数的浮点常量判断,可以扩展逻辑:将浮点常量不断乘以2直到小数部分为0,统计乘2的次数不超过对应类型的尾数位即可,该逻辑同样可以编译期实现。
- 如果编译器不支持__int128,可以替换为对应平台的大整数类型,或者使用浮点尾数位比对的逻辑实现。
内容的提问来源于stack exchange,提问作者pmor
相关产品推荐
相关产品推荐

