c++ - C/C++ : 1. 00000 <= 1.0f = 假

标签 c++ for-loop floating-accuracy

谁能解释为什么 1.000000 <= 1.0f 是假的?

代码:

#include <iostream>
#include <stdio.h>

using namespace std;

int main(int argc, char **argv)
{
    float step = 1.0f / 10;
    float t;

    for(t = 0; t <= 1.0f; t += step)
    {
        printf("t = %f\n", t);
        cout << "t = " << t << "\n";
        cout << "(t <= 1.0f) = " << (t <= 1.0f) << "\n";
    }

    printf("t = %f\n", t );
    cout << "t = " << t << "\n";
    cout << "(t <= 1.0f) = " << (t <= 1.0f) << "\n";
    cout << "\n(1.000000 <= 1.0f) = " << (1.000000 <= 1.0f) << "\n";
}

结果:

t = 0.000000
t = 0
(t <= 1.0f) = 1
t = 0.100000
t = 0.1
(t <= 1.0f) = 1
t = 0.200000
t = 0.2
(t <= 1.0f) = 1
t = 0.300000
t = 0.3
(t <= 1.0f) = 1
t = 0.400000
t = 0.4
(t <= 1.0f) = 1
t = 0.500000
t = 0.5
(t <= 1.0f) = 1
t = 0.600000
t = 0.6
(t <= 1.0f) = 1
t = 0.700000
t = 0.7
(t <= 1.0f) = 1
t = 0.800000
t = 0.8
(t <= 1.0f) = 1
t = 0.900000
t = 0.9
(t <= 1.0f) = 1
t = 1.000000
t = 1
(t <= 1.0f) = 0

(1.000000 <= 1.0f) = 1

最佳答案

正如评论中正确指出的那样,t 的值实际上与您在下面的行中定义的 1.00000 不同。

使用 std::setprecision(20) 以更高的精度打印 t 将显示其实际值:1.0000001192092895508

避免此类问题的常用方法是不与 1 进行比较,而是与 1 + epsilon 进行比较,其中 epsilon 是一个非常小的数字,也许比您的浮点精度高一到两个数量级。

所以你可以将 for 循环条件写成

for(t = 0; t <= 1.000001f; t += step)

请注意,在您的情况下,epsilon 应该至少比最大可能的浮点误差大十倍,因为 float 被添加了十次。

正如 Muepe 和 Alain 所指出的,t != 1.0f 的原因是 1/10 不能用二进制 float 精确表示。

关于c++ - C/C++ : 1. 00000 <= 1.0f = 假,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22791764/

相关文章:

javascript - 将大数字从字符串转换为数字

javascript - JavaScript 中处理大数(BigNum)的标准方案是什么?

c++ - 在 C++ 中对科学常量使用 double 是否安全?

C++ 在 unsigned char 数组和 unsigned char vector 中扫描某些元素的最快方法是什么?

python - 如何检查一个值是否匹配一个txt文件

javascript - 使用 hasOwnProperty 的此对象扩展程序中存在错误,我不确定该错误是什么或此扩展程序在哪里

database - 如何在for循环中运行数据库插入查询

c++ - 如何在不违反 MISRA C++ 2008 要求规则 5-2-12 的情况下在 std::map 中插入项目?

c++ - 为什么尽管有一个 int vector ,但结构的大小不变

c++ - 如何将私有(private)指针作为 const 返回到指针列表?