您只能在IEEE754中(至少针对单精度和双精度二进制格式)使用相加倒数的方式构建数字(例如,
2-n
,如
1
、
1/2
、
1/4
、
1/65536
等),以满足可用于精度的位数,才能准确表示数字。
在浮点数(23位精度)
或双精度浮点数(52位精度)提供的缩放范围内,没有任何倒数幂的组合可以使您准确达到101.1。
如果您想快速了解这种倒数幂的工作原理,请参见
this answer。
将该答案中的知识应用于您的
101.1
数字(作为单精度浮点数):
s eeeeeeee mmmmmmmmmmmmmmmmmmmmmmm 1/n
0 10000101 10010100011001100110011
| | | || || || |+- 8388608
| | | || || || +
| | | || || |+
| | | || || +
| | | || |+
| | | || +
| | | |+
| | | +
| | +
| +
+
对于 101.1
,它的尾数部分实际上会无限循环:
mmmmmmmmm mmmm mmmm mmmm mm
100101000 1100 1100 1100 11|00 1100 (and so on).
因此,这不是精度问题,任何有限的位数都无法在IEEE754格式中完全表示该数字。
使用这些位计算
实际数字(最接近的近似值),符号为正。指数为128+4+1=133-127偏差=6,因此乘数为2
6或64。
尾数由1(隐式基数)加上(对于所有这些位,每个位值为1/(2
n),其中n从1开始向右增加),
{1/2, 1/16, 1/64, 1/1024, 1/2048, 1/16384, 1/32768, 1/262144, 1/524288, 1/4194304, 1/8388608}
。
将所有这些相加,得到
1.57968747615814208984375
。
当你把它乘以之前计算的乘数
64
时,你会得到
101.09999847412109375
。
所有数字均使用100位小数计算,使用bc
进行计算,因此会有很多末尾的零,因此数字应该非常准确。而且我还使用以下方式检查了结果:
#include <stdio.h>
int main (void) {
float f = 101.1f;
printf ("%.50f\n", f);
return 0;
}
这也让我得到了 101.09999847412109375000...
。