You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C++中double类型相等判断异常及循环未触发问题咨询

C++浮点数精度相关问题解答

代码示例

#include <iostream>
#include <math.h>
#include <vector>

int main() {
    size_t N = 20;
    double from = 0.0;
    double to = 1.0;

    std::vector<double> xVec{};

    double h = (to - from) / double(N);
    for (double x = from; x <= to; x += h) { // 未进入x == 1.0的迭代
        xVec.push_back(x);
        std::cout << x << "\n";
    }

    std::cout << "\n";

    double x = 0.9;
    const std::vector<double>::iterator it = std::lower_bound(xVec.begin(), xVec.end(), x);
    std::cout << x << " " << *it << " " << (x == *it) << "\n"; // 显示0.9 != 0.9
}

运行输出

0
0.05
0.1
0.15
0.2
0.25
0.3
0.35
0.4
0.45
0.5
0.55
0.6
0.65
0.7
0.75
0.8
0.85
0.9
0.95

0.9 0.9 0

疑问1:为何循环条件x <= to无法进入x == 1.0的迭代?

这是浮点数的二进制表示精度限制导致的:

  • 十进制的0.05无法被二进制浮点数精确存储,它在二进制中是无限循环小数,实际存储的是一个近似值。
  • 每次循环执行x += h时,都会累积这个微小的误差,经过20次累加后,最终结果会略大于1.0(而非精确等于)。
  • 当循环到x = 0.95时,执行x += h后,x的实际值会比1.0大一点,此时x <= to(to是精确的1.0)的条件不成立,循环终止,因此不会进入x == 1.0的迭代。

疑问2:为何std::lower_bound返回的double值与直接赋值的0.9相等判断结果为false?

核心原因还是浮点数的近似存储特性:

  • 向量中的0.9是通过多次累加近似的0.05得到的,是多次误差累积后的近似结果。
  • 直接赋值的double x = 0.9,是将十进制0.9直接转换为二进制浮点数的近似值,这个值和累加得到的0.9在二进制存储上存在细微差异。
  • 浮点数的==操作是精确的二进制位比较,只要两个值的二进制表示有任何差异,结果就是false。

如果需要判断两个浮点数是否“实际相等”,应该通过比较它们的差值是否小于一个极小的阈值,示例代码如下:

#include <limits>
// ...
bool isEqual = std::abs(x - *it) < 10 * std::numeric_limits<double>::epsilon();

内容的提问来源于stack exchange,提问作者Daniel

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.05 23:35:14