IEEE 754 添加两个 32 位浮点数(-1 和 2^(-50) )
IEEE 754 Addition of two 32-bit floating point numbers (-1 and 2^(-50) )
考虑以下 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,从而忽略了较小的数字?
在此先感谢您的帮助!
您正在使用 float
,它(至少)是单精度的。请改用 double
。
并且 -1+9e-16
在 -1
的单精度舍入范围内。
IEEE 754 标准指定 1 个符号位、7 个指数位和 24 个尾数位。执行加法时,每个数字的尾数都会被归一化,因此 2^-50 是 1 相对于 1 右移 50 位。这导致它落在用于结果的 24 位尾数之外。你应该尝试用 2^-25 重复你的实验来证明这一点。
考虑以下 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,从而忽略了较小的数字?
在此先感谢您的帮助!
您正在使用 float
,它(至少)是单精度的。请改用 double
。
并且 -1+9e-16
在 -1
的单精度舍入范围内。
IEEE 754 标准指定 1 个符号位、7 个指数位和 24 个尾数位。执行加法时,每个数字的尾数都会被归一化,因此 2^-50 是 1 相对于 1 右移 50 位。这导致它落在用于结果的 24 位尾数之外。你应该尝试用 2^-25 重复你的实验来证明这一点。