IEEE 754实数可以覆盖其范围内的所有整数吗?

gre*_*man 17 math

原始问题被编辑(缩短)以关注精度问题,而不是范围问题.

单精度或双精度,实数的每个表示都限于( - 范围,+范围).在这个范围内有一些整数(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

pha*_*t0m 29

不,不是全部,但存在一个范围,您可以在其中准确地表示所有整数.

32位浮点数的结构

32位浮点类型使用

  • 1位为标志
  • 指数为8位
  • 分数为23位(隐含1)

代表数字

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

(-)1.xxxx_xxxx_xxxx_xxxx_xxxx_xxx (binary)
Run Code Online (Sandbox Code Playgroud)

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

要使它表示需要n位的整数,您需要将其n-1向左移位.(x超出浮点的所有es都只是零)

用24位表示整数

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

1xxx_xxxx_xxxx_xxxx_xxxx_xxxx.0 (unbiased exponent = 23)
Run Code Online (Sandbox Code Playgroud)

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

我们以这种方式代表的最高数字是:

1111_1111_1111_1111_1111_1111.0
Run Code Online (Sandbox Code Playgroud)

要么 2^24 - 1 = 16777215

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

用25位表示整数

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

1_xxxx_xxxx_xxxx_xxxx_xxxx_xxx0.0
Run Code Online (Sandbox Code Playgroud)

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

找到最大值

我们可以通过简单地分配给所有es 来表示`1_0000_0000_0000_0000_0000_0000形式.下一个更高的整数是:.很容易看出这个数字无法准确表示,因为表单不允许我们将最后一个数字设置为:它始终是.1_xxxx_xxxx_xxxx_xxxx_xxxx_xxx0.01x1_0000_0000_0000_0000_0000_000110

接下来,1后面跟着24个零是我们可以准确表示的整数的上界.下限只是将其符号位翻转.

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

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

64位浮点数的结构

  • 1位为标志
  • 11个指数位
  • 52个分数位

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

  • 2 54为上限
  • -2 54为下限

通过对64位浮点数的结构应用相同的论证,可以很容易地实现这一点.

注:这是不是说这些都是所有的整数,我们可以代表,但它可以让你在其中你可以代表一定范围的所有整数.超出该范围,我们只能表示2的幂乘以所述范围的整数.

组合论证

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

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

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

  • @macias:是的,所有数字都以二进制数字开头.唯一没有的数字是零.(它有一个特殊的代表).此外,移位和乘以2的幂是相同的.我不确定你对`1.5`例子的意思.在二进制中,即"1.1",无偏指数为0. (2认同)
  • @macias啊,我想我看到了误解所在.我所有的`x`都是二进制数字.将十进制"1.5"以二进制形式向左移动一个位置将产生"3":`1.5 = 1.1b` - >`11.0b = 3` (2认同)
  • @macias你的意思是"你不转移的东西"是什么意思?实际将十进制"0.5"作为二进制IEEE754 FP存储的方式是:`0__0111_1110__000_0000_0000_0000_0000_0000`:符号为零,偏置指数为126,加偏置为-127给出无偏指数-1,小数部分为0前置前导,你有:1.00 ...(二进制)*2 ^ -1,二进制为0.1,十进制为0.5. (2认同)

Dav*_*men 7

macias,加入phant0m已经很好的答案(upvoted;我建议你接受它),我会用你自己的话.

"不,它不能完成,例如,数字16777217并不完全由浮点数表示."

此外,"例如,编号9223372036854775809未完全由双数表示".

这假设您的计算机使用IEEE浮点格式,这是一个相当强大的赌注.


Kei*_*son 6

不。

例如,在我的系统上,该类型float最多可以表示大约 的值3.40282e+38。作为一个整数,这将是大约340282000000000000000000000000000000000,或大约 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;
}
Run Code Online (Sandbox Code Playgroud)

我的系统上的输出是:

x = 1267650600228229401496703205376.0
y = 1267650751343956853325350043648.0
Run Code Online (Sandbox Code Playgroud)

另一种看待它的方式:

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

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

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