计算机的浮点运算,计算机只能计算整数

1/3+1/6=计算机是如何得出0.5的?
两个无限循环小数相加,运算器是如何处理的?

首先,虽然1/3和1/6都是无限循环小数,但在CPU里,位数都是有限的,参见:浮点数_百度百科,英语好的可以看Single-precision floating-point format

所以实际上1/3和1/6在内存里不是长度无限的,具体来说,以gcc 481作为测试环境的话,大概是这样的:

1/3在内存里是0x3eaaaaab
1/6在内存里是0x3E2AAAAB

这两个数字如果换算成十进制小数,那么应该是:

1/3 => 0.3333333432674407958984375
1/6 => 0.16666667163372039794921875

也就是说,这两个数本身在内存就是不精确的。

因为计算机内部都是二进制的,这两个数值用二进制表示是这样的:

1/3 => 0.01010101010101010101011
1/6 => 0.001010101010101010101011

现在计算机做浮点都是硬浮点,那么具体的计算过程都是由CPU来完成的。

1/3+1/6 = 0.01010101010101010101011 + 0.001010101010101010101011

具体过程:

  0.010101010101010101010110
+ 0.001010101010101010101011
--------------------------------
  0.100000000000000000000001

因为这个时候精度已经多出一位了,此时CPU要做一个取舍,根据Intel的手册(参见这里浮点处理和指令编码(更新完毕))

(注:实际CPU未必是这种位对齐的算法,具体要看硬件实现)

这种情况下,最后的位数是01默认是舍掉的。

所以最终的结果就是0.10000000000000000000000,这个数字正好就是十进制的0.5

具体二进制十进制转换过程可以参考一下:十进制转二进制

参考代码:

#include 
#include 
int main()
{
    float x = 1.0/3, y = 1.0/6;
    unsigned int a, b;
    memcpy(&a, &x, sizeof(a));
    memcpy(&b, &y, sizeof(b));
    printf("%.100f %.100f %.100f\n", x, y, x + y);
    printf("%x %x\n", a, b);
    return 0;
}

你可能感兴趣的:(计算机的浮点运算,计算机只能计算整数)