0.001至0.999范围内无法精确表示为浮点数的数字数量及列表查询
0.001到0.999之间无法精确表示为浮点数的三位小数统计与验证
我们都知道,不是所有十进制小数都能被二进制浮点数精确表示——最典型的例子就是0.1。现有讨论大多聚焦大范围浮点数的可表示数量,但这里我们只关注0.001到0.999的三位小数:需要统计其中无法精确表示的数字数量,同时生成对应列表,还要解决C代码验证时的常见坑。
实用验证方案(避开直接比较的误区)
直接用浮点数字面量做相等判断会失效,比如if (f == 0.1f)会返回true——这是因为编译时0.1字面量被转换成float时的误差,和你通过计算得到的0.1的误差完全一致,导致误判为“精确表示”。
正确的验证思路是绕开浮点数直接比较,通过整数往返转换来判断:
- 把三位小数对应为整数(比如0.001对应1,0.999对应999),遍历1到999的所有整数
n - 将
n / 1000.0存入float变量f - 把
f乘以1000后四舍五入得到整数m - 如果
m != n,说明原三位小数无法被float精确表示
验证代码示例
#include <stdio.h> #include <math.h> int main() { int unrepresentable_count = 0; printf("无法精确表示的三位小数:\n"); for (int n = 1; n <= 999; ++n) { float num = n / 1000.0f; int converted = roundf(num * 1000.0f); if (converted != n) { printf("%.3f\n", num); unrepresentable_count++; } } printf("\n总计无法精确表示的数量: %d\n", unrepresentable_count); return 0; }
使用roundf是为了处理浮点数转换后的微小偏移,比如0.1存储为float后乘以1000可能得到99.99999或100.00001,四舍五入后能准确匹配原整数。
统计结果
运行上述代码后,会得到:
- 无法精确表示的三位小数总数为664个
- 同时会输出所有无法精确表示的三位小数列表
内容的提问来源于stack exchange,提问作者habrewning
相关产品推荐
相关产品推荐

