c++ - float 是否可以返回 0.0 减去两个不同的值?

标签 c++ floating-point

由于浮点“近似”性质,两组不同的值可能返回相同的值。

Example :

#include <iostream>

int main() {
    std::cout.precision(100);

    double a = 0.5;
    double b = 0.5;
    double c = 0.49999999999999994;

    std::cout << a + b << std::endl; // output "exact" 1.0
    std::cout << a + c << std::endl; // output "exact" 1.0
}

但是减法也可以吗?我的意思是:是否有两组不同的值(保留其中一个值)返回 0.0

a - b = 0.0a - c = 0.0,给定一些 a,ba,c 的集合> 与 b != c??

最佳答案

IEEE-754 标准经过精心设计,当且仅当两个值相等时,减去两个值会产生零,除非从自身减去无穷大会产生 NaN 和/或异常。

不幸的是,C++ 不需要符合 IEEE-754,许多 C++ 实现使用 IEEE-754 的某些特性但并不完全符合。

一种常见的行为是将次正常的结果“刷新”为零。这是硬件设计的一部分,以避免正确处理次等结果的负担。如果此行为有效,则两个非常小但不同的数字相减可能会产生零。 (数字必须接近正常范围的底部,在低于正常范围内有一些有效位。)

有时具有这种行为的系统可能会提供一种禁用它的方法。

另一个需要注意的行为是 C++ 不要求浮点运算按照所写的方式精确执行。它允许在中间操作和某些表达式的“收缩”中使用“超精度”。例如,a*b - c*d 可以通过使用将 ab 相乘的一个运算然后将 相乘的另一个运算来计算>cd 并从先前计算的 a*b 中减去结果。后一种操作就像 c*d 是以无限精度计算的,而不是四舍五入到标称浮点格式。在这种情况下,a*b - c*d 可能会产生非零结果,即使 a*b == c*d 的计算结果为 true。

一些 C++ 实现提供了禁用或限制此类行为的方法。

关于c++ - float 是否可以返回 0.0 减去两个不同的值?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54531425/

相关文章:

windows - "Calculator bug"是代码问题吗?

c++ - 浮点 C++ 编译器选项 |防止 a/b -> a* (1/b)

c++ - 动态数组的运算符重载给出奇怪的错误

除法和 cout 的 C++ 问题

c# - 如果不对 float 进行任何操作, float 会失去精度吗

c++ - 使用 int 指针的 float 的位表示

c++ - 使用 visual studio 9 构建的命令行应用程序不将 *.NEF 作为输入,而使用 gcc 构建的同一个应用程序却接受 - 为什么?

c++ - 在 OSX 上更新 GCC

c++ - 我可以将 void* 指针分配给 char* 指针吗?

c++ - Winsock: Overlapped AcceptEx 指示新连接,而没有客户端连接