APP下载

为什么计算机无法准确储存0.1

消息来源:baojiabao.com 作者: 发布时间:2024-05-19

报价宝综合消息为什么计算机无法准确储存0.1

在人们的印象中,计算机是非常精确的机器,如果不出bug,程式总能给出正确的结果.像网银/支付宝这些软件,一分一厘都算得清清楚楚.但其实在计算机内部,许多运算并不是100%精确,而是用近似的手段完成的,因为计算机并不能精确储存小数,这是计算机的"原罪",所以在应用中,只能通过控制误差足够小来保证得到一个合理的结果.举个例子,在实际生活中,人民币结算只需要两位小数,分是最小的单位.一分钱,0.01元,可能用0.010009765625来近似.

为什么计算机存不准小数呢?

简单地说,计算机内部使用二进位制,在处理整数的时候,没有问题:

比如十进位制的108,可以写成108=64+32+8+4,即 108 = 2^6 + 2^5 + 2^3 + 2^2, 二进位制表示为 01101100.2^n是构建一个整数的要素.

相应地,在处理小数的时候,这些要素变成了1/2,1/4,1/8,1/16...即2^-1,2^-2,2^-3,2^-4...

比如0.3125 = 1/4 + 1/16,0.3125是可以存准的,但是0.1这种,就只能近似表示了.

以双精度浮点数(double)为例,double型别具有64个二进位制位,根据以下规则计算:

数值=(-1)^sign * 2^(exponent-1023) * 1.mantissa

其中1.mantissa是二进位制表示的小数.譬如二进位制1.1换成十进位制是1+2^-1 = 1.5; 二进位制1.011换成十进位制是 1+2^-2 + 2^-3 = 1.375.

笔者做了一个实验来说明0.1的储存情形.

#include

void bin(unsigned n)

{

unsigned i;

for (i = 1 0; i = i / 2)

(n & i)? printf("1"): printf("0");

printf(" ");

}

int main()

{

double d = 0.1;

unsigned * up =(unsigned *) &d;

unsigned int i = 0;

bin(*up);

bin(*(up+1) );

for(i = 1; i

{

printf("%.*2$f ", d,i);

}

return 0;

}

输出:

10011001100110011001100110011010

00111111101110011001100110011001

0.1

0.10

0.1000

0.10000000

0.1000000000000000

0.10000000000000000555111512312578

0.1000000000000000055511151231257827021181583404541015625000000000

0.10000000000000000555111512312578270211815834045410156250000000000000000000000000000000000000000000000000000000000000000000000000

在计算机内部,实际上存的是这个数:

0.1000000000000000055511151231257827021181583404541015625.

这个数二进位制位的情况:

验证一下上面的数值计算规则:

数值 = (-1)^0 * 2^(1019-1023) * (1 + 2^-1+2^-4+2^-5+2^-8+2^-9+2^-12+2^-13+2^-16+2^-17+2^-20+2^-21+2^-24+2^-25+2^-28+2^-29+2^-32+2^-33+2^-36+2^-37+2^-40+2^-41+2^-44+2^-45+2^-48+2^-49+2^-51)

(1 + 2^-1+2^-4+2^-5+2^-8+2^-9+2^-12+2^-13+2^-16+2^-17+2^-20+2^-21+2^-24+2^-25+2^-28+2^-29+2^-32+2^-33+2^-36+2^-37+2^-40+2^-41+2^-44+2^-45+2^-48+2^-49+2^-51) 计算结果为:

1.600000000000000088817841970012523233890533447265625

乘以第二项 2^-4 即 1/16. 结果为:

0.1000000000000000055511151231257827021181583404541015625

和程式打印的结果一致.

2019-11-04 17:57:00

相关文章