原始问题经过编辑(缩短(,以关注精度问题,而不是范围问题。
单精度或双精度,实数的每个表示形式都限制为 (-范围,+范围(。在这个范围内有一些整数(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
不,不是全部,但存在一个范围,您可以在该范围内准确表示所有整数。
32位浮点数的结构
32 位浮点类型使用
- 符号为 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)
因为我们可以将 x
ES 随意设置为 1
或 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_0000 with the form
1_xxxx_xxxx_xxxx_xxxx_xxxx_xxx0.0 , by simply assigning
1 to all
x es. The next higher integer from that is:
. 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 : It is always
0"。因此,1
后跟 24 个零是我们可以准确表示的整数的上限。下限只是将其符号位翻转。
可以表示所有整数的范围(包括边界(
- 224 作为上限
- -224 作为下限
64位浮点数的结构
- 符号为 1 位
- 11 指数位
- 52 个小数位
可以表示所有整数的范围(包括边界(
- 253 作为上限
- -253 作为下限
通过将相同的参数应用于 64 位浮点数的结构,这很容易实现。
注意:这并不是说这些都是我们可以表示的整数,但它为您提供了一个可以表示所有整数的范围。超出该范围,我们只能表示 2 的幂乘以所述范围内的整数。
组合论证
简单地说服自己,32位浮点数不可能代表32位整数可以表示的所有整数,我们甚至不需要看浮点数的结构。
- 对于 32
- 位,我们可以表示 232 种不同的东西。不多也不少。
- 一个 32 位整数使用所有这些"事物"来表示数字(成对不同(。
- 32 位浮点数可以表示至少一个带有小数部分的数字。
因此,除了所有 2 个32 个整数之外,32 位浮点数不可能表示这个小数。
macias,以添加到 phant0m 已经很好的答案中(赞成;我建议你接受(,我会用你自己的话。
"不,这是不可能的,例如数字16777217不是用浮点数准确表示的。">
此外,"例如,数字9223372036854775809不能完全用双精度数字表示"。
这是假设您的计算机使用的是IEEE浮点格式,这是一个非常有力的赌注。
No.
例如,在我的系统上,类型 float
最多可以表示大约 3.40282e+38
的值。作为一个整数,大约是340282000000000000000000000000000000000
,或大约2128。
float
的大小为 32 位,因此它最多可以精确表示 232 个不同的数字。
整数对象通常使用其所有位来表示值(1 位专用于有符号类型的符号位(。浮点对象使用其一些位来表示指数(IEEE 32 位为 8 位float
(;这增加了其范围,但代价是失去精度。
一个具体的例子(1267650600228229401496703205376.0
是2100,可以精确地表示为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 = %.1fn", x);
printf("y = %.1fn", y);
return 0;
}
我的系统上的输出是:
x = 1267650600228229401496703205376.0
y = 1267650751343956853325350043648.0
另一种看待它的方式:
一个 32位对象最多可以表示 232 个不同的值。
32 位有符号整数可以表示 -2147483648
范围内的所有整数值。 2147483647
(-231 .. +231-1(。
32 位float
可以表示 32 位有符号整数不能表示的许多值,因为它们是小数 (0.5( 或因为它们太大 (2.0100(。 由于有些值可以用 32 位float
表示,但不能用 32 位int
表示,因此必须有其他值可以用 32 位int
表示,但不能用 32 位float
表示。 这些值是整数,其有效位数多于float
可以处理的位数,因为int
有 31 个值位,但float
只有大约 24 个。
您是在问 Real 数据类型是否可以表示其范围内的所有整数值(绝对值高达 FLT_MAX 或 DBL_MAX,C 或其他语言中的类似常量(。
存储在K 位中的浮点数表示的最大数字通常比 K 位可以表示的 2^K 整数数大得多,因此答案通常是否定的。 32 位 C 浮点数超过 10^37,32 位 C 整数小于 10^10。 要找出某个数字之后的下一个可表示数字,请使用 nextafter(( 或 nextafterf((。 例如,代码
printf ("%20.4f %20.4fn", nextafterf(1e5,1e9), nextafterf(1e6,1e9));
printf ("%20.4f %20.4fn", nextafterf(1e7,1e9), nextafterf(1e8,1e9));
打印输出
100000.0078 1000000.0625
10000001.0000 100000008.0000
您可能对是否可以精确表示介于两个附近的小数浮点值 R 和 S 之间的整数 J 感兴趣,假设 S-R <1 和 R 我还没有填写所有细节来表明 J*P-U <P,但在假设>
每个浮点数是某个整数和 2 的幂的乘积或比率(如上面提到的两段(,在该浮点文章中也讨论了,在开头的一段中: 就其性质而言,所有以浮点格式表示的数字都是有理数,在相关基数中具有终止扩展(例如,...以 2 为基数的终止二进制扩展(。无理数(如 π 或 √2(或非终止有理数必须近似。精度的位数(或位(也限制了可以精确表示的有理数集。