【发布时间】:2021-12-14 16:35:41
【问题描述】:
考虑以下一段 C++ 代码:
#include <iostream>
#include <cmath>
using namespace std;
int main()
{
cout.precision(1000000000);
float a,b,c;
a = 1;
b = -1;
c = pow(2, -50);
cout << "a = " << a << endl;
cout << "b = " << b << endl;
cout << "c = " << c << endl;
float ab = a + b;
float bc = b + c;
float abc = ab + c;
float bca = bc + a;
cout << "a + b = " << ab << endl;
cout << "b + c = " << bc << endl;
cout << "(a + b) + c = " << abc << endl;
cout << "(b + c) + a = " << bca << endl;
return 0;
}
产生输出:
a = 1
b = -1
c = 8.8817841970012523233890533447265625e-16
a + b = 0
b + c = -1
(a + b) + c = 8.8817841970012523233890533447265625e-16
(b + c) + a = 0
为什么 b + c = -1?
我无法理解 IEEE 754 标准的这种影响。
据我了解,指数范围从 -126 到 127。(偏置指数为 8 位,偏置为 127。)
所以 2^(-50) 可以毫无问题地表示为 1 或 -1。如果我正确理解标准,它们都不是次规范(非规范化)数字。
但是为什么-1 + 2^(-50)的加法会导致-1,从而忽略较小的数字呢?
提前感谢您的帮助!
【问题讨论】:
-
相比
-1,2^(-50)基本算不了什么。double只能得到 15-16 位或精度,将8.9e-16添加到 -1 基本上是舍入误差。 -
十进制数学提示:什么是 1.00 + 0.00100,四舍五入到 3 位有效数字?
-
@PeteBecker:IEEE-754 单精度二进制数根本没有十进制数字,将它们视为十进制数字是一种误导模型,会导致错误。 1.40129846432481707092372958328991613128026194187651577175706828388979108268586060148663818836212158203125•10^−45 有 105 个有效数字,但准确表示为无特别是,将“噪声”视为格式精度的一部分,而不是由执行的计算产生的,这会干扰正确计算误差范围。
-
初学者最好被告知每个操作,包括十进制数字和二进制浮点格式之间的转换,可能会在每个值时引入一些“噪音” 正好代表一个数字。这就是它在 IEEE-754 标准中的规定,也是正确设计、推理、分析和调试浮点代码所需的模型。你有一个浮点数并不是事实,这意味着一些数字是“噪音”;事实上,您使用的运算只能逼近实数算术,这会给您带来“噪音”。
-
圆运算和浮点运算都是数字,这不是一个难理解的概念。
标签: c++ floating-point addition ieee-754