1

如果 a 的大小float是 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
4

1 回答 1

2

这些值-8,388,608 ... 8,388,607使我相信您认为浮点数使用二进制补码,而事实并非如此。无论如何,您拥有的范围表示 24 位,而不是您从四个字节中获得的 32 位。

C 中的浮点数使用IEEE754表示,它基本上包含三个部分:

  • 标志。
  • 指数(某种比例)。
  • 分数(数字的实际数字)。

您基本上可以获得一定的精度(例如 7 个十进制数字),而指数决定了您是否将这些精度用于 0.000000001234567 或 123456700000 之类的数字。

您在末尾获得这些额外数字的原因0.1是因为该数字无法在 IEEE754 中精确表示。请参阅此答案以获取解释为什么会这样的论文。

只有当可以通过在精度位数(即分数中的位数)内添加 2 的逆幂(如1/21/161/65536

因此,例如,数字 like0.5是可以的,因为它是1/2. 同样0.8125是可以的,因为它可以从1/2,1/4和构建1/16

没有办法(至少在 23 位精度内)可以0.1从 2 的逆幂构建,因此它为您提供最接近的匹配。

于 2012-08-29T01:12:17.823 回答