浮点小数的精度?

时间:2012-08-29 01:08:44

标签: objective-c c floating-point

如果float的大小是4个字节,则它不应该能够保存从8,388,607-8,388,608或其周围某处的数字,因为我可能错误地计算了它。 / p>

为什么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

1 个答案:

答案 0 :(得分:2)

-8,388,608 ... 8,388,607让我相信你认为花车使用两个补码,但他们没有。在任何情况下,你所拥有的范围都表示24位,而不是你从四个字节得到的32位。

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

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

您基本上可以获得一定的精确度(例如7位十进制数字),而指数则指示您是否使用这些精度为0.000000001234567或123456700000。

您在0.1结尾处获得这些额外数字的原因是因为该数字无法在IEEE754中完全表示。请参阅this answer以获取解释原因的论文。

如果可以通过在精度位数内添加两个反幂(如1/21/161/65536等)来构建数字,则只能精确表示数字(即,分数中的位数),受缩放影响。

因此,例如,像0.5这样的数字是可以的,因为它是1/2。同样地,0.8125也可以,因为它可以从1/21/41/16构建。

没有办法(至少在23位精度范围内)你可以从2的反幂建立0.1,所以它给你最近的匹配。