当一个加入一个大数字时,浮点运算如何工作?

时间:2013-08-16 08:19:39

标签: c++ floating-point

如果我们运行此代码:

 #include <iostream>
 int main ()
 { 
     using namespace std;
     float a = 2.34E+22f;
     float b = a+1.0f;  
     cout<<"a="<<a<<endl;
     cout<<"b-a"<<b-a<<endl;
     return 0;
 }

然后结果将为0,因为浮点数只有6位有效数字。但是浮点数1.0试图添加到23位数字。那么,程序如何意识到数字1没有位置,算法是什么?

3 个答案:

答案 0 :(得分:1)

基本原则是两个数字对齐,小数点位于同一位置。我使用10位数字使其更容易阅读:

 a = 1.234E+10f;
 b = a+1.0f;

计算+ 1.0f时,需要排列小数点:

 1.234E+10f becomes 1234000000.0
 1.0f       becomes          1.0
            + 
            =       1234000001.0

但是由于它的浮动,右边的1超出了有效范围,所以存储的数字将是1.234000E+10 - 除此之外的任何数字都会丢失,因为没有足够的数字。

[注意,如果在优化编译器上执行此操作,它仍可能显示1.0作为差异,因为浮点单元使用64位或80位内部表示,因此如果计算完成而不存储中间体得到一个变量(一个体面的编译器当然可以在这里实现)2.34E + 22f保证不适合64位浮点数,也可能不适用于80位浮点数。

答案 1 :(得分:1)

一步一步:

IEEE-754 32位二进制浮点格式:

    sign         1 bit
    significand 23 bits
    exponent     8 bits

I)float a = 23400000000.f;

23400000000.f转换为float

23,400,000,000 = 101 0111 0010 1011 1111 1010 1010 0000 00002
               = 1.01011100101011111110101010000000002 • 234.

但有效点只能在该点后存储23位。所以我们必须围绕:

  1.01011100101011111110101 010000000002 • 234
≈ 1.010111001010111111101012 • 234

所以,之后:

float a = 23400000000.f;

a等于23,399,991,808。

II)float b = a + 1;

a = 101011100101011111110101000000000002.
b = 101011100101011111110101000000000012
  = 1.01011100101011111110101000000000012 • 234.

但是,有效点再次只能存储23个二进制数字。所以我们必须围绕:

  1.01011100101011111110101 000000000012 • 234
≈ 1.010111001010111111101012 • 234

所以,之后:

float b = a + 1;

b等于23,399,991,808。

III)float c = b - a;

101011100101011111110101000000000002 - 101011100101011111110101000000000002 = 0

此值可以存储在float中,而不会进行舍入。

所以,之后:

float c = b - a;

с等于0.

答案 2 :(得分:0)

添加两个FP编号时,它们首先转换为相同的指数。十进制: 2.34000E+22 + 1.00000E0 = 2.34000E22 + 0.000000E+22。在此步骤中,1.0将丢失以进行舍入。

二进制浮点的工作原理基本相同,只是E + 22被2 ^ 77取代。