为什么IEEE754单精度浮点数只有7位精度?

时间:2013-10-02 05:16:08

标签: c# java .net variables types

为什么单精度浮点数具有7位精度(或15-16位精度)?

任何人都可以根据为浮点数分配的32位(Sign(32)Exponent(30-23),Fraction(22-0))解释我们是如何到达的吗?

2 个答案:

答案 0 :(得分:8)

有效数的23个小数位(22-0)出现在存储器格式中,但总精度实际上是24位,因为我们假设有一个前导1.这相当于log10(2^24) ≈ 7.225个十进制数字。

双精度浮点数的分数为52位,前导1为53.因此双精度数可以保持log10(2^53) ≈ 15.955十进制数,而不是16位。

注意:前导1不是符号位。它实际上是(-1)^sign * 1.ffffffff * 2^(eeee-constant)但我们不需要在分数中存储前导1。必须仍然存储符号位


有些数字不能表示为2的幂之和,例如1/9:

>>>> double d = 0.111111111111111;
>>>> System.out.println(d + "\n" + d*10);
0.111111111111111
1.1111111111111098

如果财务计划在没有自我纠正的情况下反复进行此计算,最终会出现差异。

>>>> double d = 0.111111111111111;
>>>> double sum = 0;
>>>> for(int i=0; i<1000000000; i++) {sum+=d;}
>>>> System.out.println(sum);
111111108.91914201

经过10亿次总结,我们错过了超过2美元。

答案 1 :(得分:0)

32 float有23位,因此最小单位为

2^(-23) = 0.00000011920928955078125

其他数字仅大于0.00000011920928955078125。并非不可能小于0.00000011920928955078125。其他数字由0.00000011920928955078125

0.00000011920928955078125 * n

因此,我们可以轻松地表达0.00000x [1-9]。float32当然可以具有6位数字的精度。不用考虑舍入,我们可以将以下7位数字计算为:

0.00000011920928955078125 * 1 = 0.0000001
0.00000011920928955078125 * 2 = 0.0000002
0.00000011920928955078125 * 3 = 0.0000003
0.00000011920928955078125 * 4 = 0.0000004
0.00000011920928955078125 * 5 = 0.0000005
0.00000011920928955078125 * 6 = 0.0000007
0.00000011920928955078125 * 7 = 0.0000008
0.00000011920928955078125 * 8 = 0.0000009
0.00000011920928955078125 * 9 = 0.000001

它不能表示0.0000006。这是float32具有6〜7位精度的结果,我们可以在互联网上找到它。