如果afloat
的大小是4字节,那么它不应该能够容纳从8,388,607
到-8,388,608
的数字,或者在那里的某个地方,因为我可能计算错了。
为什么f
显示额外的15
,因为f
(0.1)的值仍然在8,388,607
到-8,388,608
之间?
int main(int argc, const char * argv[])
{
@autoreleasepool {
float f = .1;
printf("%lu", sizeof(float));
printf("%.10f", f);
}
return 0;
}
2012-08-28 20:53:38.537 prog[841:403] 4
2012-08-28 20:53:38.539 prog[841:403] 0.1000000015
最佳答案
值-8,388,608 ... 8,388,607
让我相信你认为浮点数使用的是2的补码,而不是2的补码。在任何情况下,你拥有的范围表示24位,而不是从4个字节得到的32位。
C中的float使用IEEE754表示,基本上有三个部分:
标志。
指数(有点像刻度)。
分数(数字的实际数字)。
你基本上得到了一定的精度(比如7个十进制数字),指数决定了你是用这些来表示0.000000001234567还是12345670000。
您在0.1
结尾处获得这些额外数字的原因是,IEEE754中无法精确表示该数字。参见this answer一篇解释原因的论文。
只有通过在精度位数(即小数位数)内添加两个倒数的幂(如1/2
、1/16
、1/65536
等)才能精确地表示数字,并可缩放。
例如,像0.5
这样的数字是可以的,因为它是1/2
。类似地,可以从0.8125
、1/2
和1/4
构建1/16
。
不可能(至少在23位精度内)用2的逆幂来构建0.1
,所以它给了你最接近的匹配。
关于objective-c - 浮点小数的精度?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/12169614/