Jer*_*emy 2 c c++ floating-point floating-point-conversion
可能重复:
浮点比较
我对C/C++中float的准确性有疑问.当我执行以下程序时:
#include <stdio.h>
int main (void) {
float a = 101.1;
double b = 101.1;
printf ("a: %f\n", a);
printf ("b: %lf\n", b);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
结果:
a: 101.099998
b: 101.100000
Run Code Online (Sandbox Code Playgroud)
我相信浮点数应该是32位,所以应该足以存储101.1为什么?
pax*_*blo 11
只能表示恰好在IEEE754(至少对于单和双精度的二进制格式),如果他们可以从加入一起反转权力来构建数2(即,像,,,等等)受到可用的比特的数量为了精确.2-n11/21/41/65536
在浮点数(23位精度)或双精度(52位精度)提供的缩放中,没有两种反转功率的组合可以精确到达101.1 .
如果你想要一个快速的教程,说明这两种倒置功能的工作原理,请参阅这个答案.
将该答案的知识应用于您的101.1数字(作为单个精确浮点数):
s eeeeeeee mmmmmmmmmmmmmmmmmmmmmmm 1/n
0 10000101 10010100011001100110011
| | | || || || |+- 8388608
| | | || || || +-- 4194304
| | | || || |+----- 524288
| | | || || +------ 262144
| | | || |+--------- 32768
| | | || +---------- 16384
| | | |+------------- 2048
| | | +-------------- 1024
| | +------------------ 64
| +-------------------- 16
+----------------------- 2
Run Code Online (Sandbox Code Playgroud)
尾数的一部分实际上永远持续下去101.1:
mmmmmmmmm mmmm mmmm mmmm mm
100101000 1100 1100 1100 11|00 1100 (and so on).
Run Code Online (Sandbox Code Playgroud)
因此,它不是精确的问题,任何数量的有限位都不能完全代表IEEE754格式的数字.
使用这些位来计算实际数量(最接近的近似值),符号为正.指数为128 + 4 + 1 = 133 - 127 bias = 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.
所有数字都是bc使用100个十进制数字的比例计算的,因此产生了大量的尾随零,因此数字应该非常准确.双重如此,因为我检查了结果:
#include <stdio.h>
int main (void) {
float f = 101.1f;
printf ("%.50f\n", f);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
这也给了我101.09999847412109375000....