IEEE 754:它究竟是如何工作的?

时间:2011-08-10 04:20:34

标签: c floating-point floating-accuracy ieee-754

为什么以下代码的行为与在C中的行为相同?

float x = 2147483647; //2^31
printf("%f\n", x); //Outputs 2147483648

这是我的思考过程:

2147483647 =   0      1001 1101      1111 1111 1111 1111 1111 111

   (0.11111111111111111111111)base2 = (1-(0.5)^23)base10
=> (1.11111111111111111111111)base2 = (1 + 1-(0.5)^23)base10 = (1.99999988)base10

因此,要将IEEE 754表示法转换回十进制:1.99999988 * 2^30 = 2147483520

从技术上讲,C程序必须打印出2147483520,对吗?

4 个答案:

答案 0 :(得分:3)

要表示的值为2147483647.可以用这种方式表示的下两个值是2147483520和2147483648.

由于后者更接近无法代表的“理想之一”,因此会使用它:在浮点数中,值会四舍五入,而不会被截断。

答案 1 :(得分:1)

The standard is available here。您可能不得不购买它,因为IEEE(以及其他类似组织)主要通过销售标准来赚钱,以支付他们组装,游说接受和提高标准质量的成本。

这些位只表示有人指定它们

  

“当我用一句话时,”Humpty Dumpty用一种轻蔑的语气说道,“它   意味着我选择它的意思 - 既不多也不少。“”   问题是,“爱丽丝说,”你是否可以说出这么多的话   不同的事情。“”问题是,“Humpty Dumpty说,”这是   掌握 - 这就是全部。“(通过镜子,第6章)

在这种情况下,IEEE决定了这些位的含义,以及printf标志%f打印出正确的相应人类表示的原因是由于该标志也遵循相同的标准。

有时您可以设法将位转换为另一种数据类型(如int)并打印出这些位的“其他”表示。 C会捕获很多正常的号码促销,但你可以混淆它,通常是在将错误类型的指针分配给正确的地址(并解除引用它们)的帮助下。

请注意,当您手动进行数学运算时,实际硬件并不能保证完全按照您的方式进行数学运算。使用整数数学,表示中的准确度要高得多,但对于浮点数学,如何舍入数字会使输出产生很大的差异。这甚至没有提到有时被烧入系统的浮点错误(幸好不经常)。

答案 2 :(得分:1)

浮点格式通常采用“标准化格式”,其中尾数的最高位始终为1.因为它始终为1,所以您不需要用一点来存储它。因此,在解码这样的数字表示时,您需要在顶部添加1。

答案 3 :(得分:1)

2147483647 = 2^31 - 1 = +1 * 2^30 * 1.1111 1111 1111 1111 1111 1111 1111 11

以IEEE 754-1985单精度格式对此数字进行编码时,有效数字会正确舍入。对于舍入模式舍入到最接近的偶数(默认舍入模式),这意味着它会被舍入。

在四舍五入之前:

exponent = 30, significand = 1.1111 1111 1111 1111 1111 1111 1111 11

将有效数字四舍五入到小数点后的23位数:

exponent = 30, significand = 10.0000 0000 0000 0000 0000 000

正常化后:

exponent = 31, significand = 1.0

以单精度格式编码:

1 | 10011110 | 00000000000000000000000