20

对原始问题进行了编辑(缩短),以关注精度问题,而不是范围问题。

单精度或双精度,实数的每种表示形式都限于 (-range,+range)。在这个范围内有一些整数(1、2、3、4...,等等;负数也是如此)。

是否保证 IEEE 754 实数(浮点数、双精度数等)可以“覆盖”其范围内的所有整数?通过“覆盖”,我的意思是实数将准确地表示整数,而不是(例如)“5.000001”。

提醒一下:http ://www3.ntu.edu.sg/home/ehchua/programming/java/DataRepresentation.html很好地解释了各种数字表示格式。

更新:

因为问题是针对“可以”的,所以我也在寻找无法做到这一点的事实——因为引用一个数字就足够了。例如“不,它不能完成,例如数字 1748574 不完全由浮点数表示”(这个数字当然是凭空得出的)。

对于好奇的读者

如果您想使用 IEEE 754 表示 - 在线计算器:http ://www.ajdesigner.com/fl_ieee_754_word/ieee_32_bit_word.php

4

4 回答 4

43

不,不是全部,但存在一个可以准确表示所有整数的范围。

32位浮点数的结构

32bit 浮点类型使用

  • 1 位符号
  • 8 位为指数
  • 23 位小数(隐含前导 1)

代表数字

基本上,您的表格中有一个数字

(-)1.xxxx_xxxx_xxxx_xxxx_xxxx_xxx (binary)

然后你用(无偏的)指数向左/向右移动。

要让它代表一个需要n位的整数,您需要将其n-1向左移动一位。(所有x超出浮点数的 es 都为零)

用 24 位表示整数

很容易看出,我们可以表示所有需要 24 位(甚至更少)的整数

1xxx_xxxx_xxxx_xxxx_xxxx_xxxx.0 (unbiased exponent = 23)

因为我们可以随意将xes设置为1or 或0.

我们可以用这种方式表示的最高数字是:

1111_1111_1111_1111_1111_1111.0

或者2^24 - 1 = 16777215

下一个更高的整数是1_0000_0000_0000_0000_0000_0000。因此,我们需要 25 位。

用 25 位表示整数

如果您尝试表示 25 位整数(无偏指数 = 24),则数字具有以下形式:

1_xxxx_xxxx_xxxx_xxxx_xxxx_xxx0.0

您可以使用的 23 位数字都已移过浮点数。前导数字始终是 1。总共有 24 位数字。但是因为我们需要 25,所以附加了一个零。

找到最大值

我们可以表示``1_0000_0000_0000_0000_0000_0000 with the form1_xxxx_xxxx_xxxx_xxxx_xxxx_xxx0.0 , by simply assigning 1 to allx es. The next higher integer from that is: 1_0000_0000_0000_0000_0000_0001 . It's easy to see that this number cannot be represented accurately, because the form does not allow us to set the last digit to 1 0` : It is always

因此,1后面跟 24 个零是我们可以准确表示的整数的上限。下限只是将其符号位翻转。

可以表示所有整数的范围(包括边界)

  • 2 24作为上限
  • -2 24作为下限

64位浮点数的结构

  • 1 位符号
  • 11个指数位
  • 52 个小数位

可以表示所有整数的范围(包括边界)

  • 2 53作为上限
  • -2 53作为下限

通过将相同的论证应用于 64 位浮点数的结构,这很容易实现。

注意:这并不是说这些都是我们可以表示的整数,但它为您提供了一个可以表示所有整数的范围。超出该范围,我们只能表示 2 乘以来自该范围的整数的幂。

组合论证

简单地说服自己 32 位浮点数不可能代表 32 位整数可以表示的所有整数,我们甚至不需要看浮点数的结构。

  1. 使用 32 位,我们可以表示 2 32种不同的事物。不多也不少。
  2. 一个 32 位整数使用所有这些“事物”来表示数字(成对不同)。
  3. 一个 32 位浮点数可以表示至少一个带有小数部分的数字。

因此,除了所有 2 32 个整数之外,32 位浮点数不可能表示这个小数。

于 2012-09-16T09:13:28.543 回答
9

macias,添加到 phant0m 已经很好的答案(赞成;我建议你接受它),我会用你自己的话。

“不,不能这样做,例如数字 16777217 不能用浮点数精确表示。”

此外,“例如数字 9223372036854775809 不完全由双数表示”。

这是假设您的计算机使用的是 IEEE 浮点格式,这是一个相当不错的选择。

于 2012-09-16T14:12:23.433 回答
7

不。

例如,在我的系统上,该类型float最多可以表示大约3.40282e+38. 作为一个整数,这将是大约2 128340282000000000000000000000000000000000或大约 2 128

的大小float为 32 位,因此它最多可以精确表示 2 32 个不同的数字。

整数对象通常使用其所有位来表示值(其中 1 位专用于有符号类型的符号位)。浮点对象使用它的一些位来表示指数(IEEE 32 位为 8 位float);这以损失精度为代价增加了它的范围

一个具体的例子(1267650600228229401496703205376.0是 2 100,并且完全可以表示为 a float):

#include <stdio.h>
#include <float.h>
#include <math.h>
int main(void) {
    float x = 1267650600228229401496703205376.0;
    float y = nextafterf(x, FLT_MAX);
    printf("x = %.1f\n", x);
    printf("y = %.1f\n", y);

    return 0;
}

我的系统上的输出是:

x = 1267650600228229401496703205376.0
y = 1267650751343956853325350043648.0

另一种看待它的方式:

一个 32 位对象最多可以表示 2 32 个不同的值。

一个 32 位有符号整数可以表示-2147483648.. 2147483647(-2 31 .. +2 31 -1) 范围内的所有整数值。

32 位float可以表示许多 32 位有符号整数不能表示的值,因为它们是小数 (0.5) 或因为它们太大 (2.0 100 )。由于存在可以用 32-bit 表示float但不能用 32-bitint表示的值,因此必须有其他值可以用 32-bit 表示int但不能用 32-bit表示float。这些值是具有比 afloat可以处理的更多有效数字的整数,因为int有 31 个值位,但float只有大约 24 个。

于 2012-09-15T21:32:02.597 回答
1

显然,您是在询问 Real 数据类型是否可以表示其范围内的所有整数值(C 中的绝对值不超过 FLT_MAX 或 DBL_MAX,或其他语言中的类似常量)。

存储在 K 位中的浮点数可表示的最大数字通常远大于 K 位可以表示的 2^K 个整数,因此通常答案是否定的。32 位 C 浮点数超过 10^37,32 位 C 整数小于 10^10。要找出某个数字之后的下一个可表示数字,请使用nextafter()或 nextafterf()。例如,代码

printf ("%20.4f %20.4f\n", nextafterf(1e5,1e9), nextafterf(1e6,1e9));
printf ("%20.4f %20.4f\n", nextafterf(1e7,1e9), nextafterf(1e8,1e9));

打印出来

     100000.0078         1000000.0625
   10000001.0000       100000008.0000

您可能对是否可以精确表示介于两个相邻小数浮点值 R 和 S 之间的整数 J 感兴趣,假设 SR < 1 和 R < J < S。是的,这样的 J 可以精确表示。每个浮点值都是某个整数和某个 2 的幂的比。(或者是某个整数和某个 2 的幂的乘积。)设 2 的幂为 P,假设 R = U/P,S = V/ P。现在 U/P < J < V/P 所以 U < J*P < V。J*P 的低位比 U、V 的低位更多为零(因为 VU < P,由于 SR < 1),所以 J 可以精确表示。

我没有填写所有细节来证明 J*PU < P 和 VJ*P < P,但在假设 SR < 1 的情况下,这很简单。下面是一个 R,J,S,P,U,V 值计算的例子: 设 R=99999.9921875 = 12799999/128,(即 P=128);让 S=100000.0078125 = 12800001/128;我们有 U=0xc34fff 和 V=0xc35001 并且它们之间有一个数字,其低阶零比任何一个都多;也就是说,J = 0xc35000/128 = 12800000/128 = 100000.0。对于此示例中的数字,请注意 U 和 V 需要 24 位来表示它们的精确表示(6 位 4 位十六进制数字)。请注意,24 位是 IEEE 754 单精度浮点数中的精度位数。(参见维基百科文章中的表格。)

每个浮点数是某个整数和某个 2 的幂的乘积或比率(如上面的两段所述)也在该浮点文章中讨论,在一段开头的段落中:

就其性质而言,所有以浮点格式表示的数字都是有理数,并在相关基数中具有终止扩展(例如,...以 2 为基数的终止二进制扩展)。无理数,例如 π 或 √2,或非终止有理数,必须近似。精度的位数(或位数)也限制了可以精确表示的有理数集。

于 2012-09-15T21:58:42.310 回答