所有的32位整数都能被精确地表示为一个双精度浮点数吗?

4

可能重复:
IEEE 754浮点数第一个无法精确表示的整数是哪个?

这是一个基本问题,我的感觉是答案是肯定的(int = 32位,double = 53位尾数+符号位)。

基本上可以触发断言吗?

int x = get_random_int();
double dx = x;
int x1 = (int) dx;
assert(x1 ==x);
if  (INT_MAX-10>x)
 {
       dx+=10;
       int x2=(int) dx;
       assert(x+10 == x2);
 }

显然,涉及除法和类似的复杂表达式的内容(例如(int)(5.0/3*3)不同于5/3*3)将不能正常工作,但我想知道转换和加减(如果没有溢出发生)是否保持等效。


1
我不会说重复,虽然我不知道重复是什么意思...我的意思是,我可以从一些A中得到我的A,但Q不同。 :) - NoSenseEtAl
@NoSenseEtAl: 本质上是在问同一个问题。对另一个问题的任何(好的)答案也将是对这个问题的好答案。 - Joachim Sauer
2个回答

5
如果尾数中的位数> =整数中的位数,则答案为是。在您的问题中,您为int和double的尾数指定了特定的已知大小,但是知道2003年的C ++标准不保证这一点很有用,该标准没有关于int和double的尾数相对大小的说明。
请注意,C和C ++不需要使用IEEE 754浮点算术。根据2003年C ++标准的3.8.1 / 8,
“浮点类型的值表示是实现定义的。”
事实上,C ++允许甚至不使用二进制尾数的浮点表示。对于C,#include 可用于推断基本类型的信息。特别地,如果FLT_RADIX的幂DBL_MANT_DIG大于或等于INT_MAX,则所有int值都可以精确表示。在C ++中,相关数量的名称为numeric_limits :: radix,numeric_limits :: digits和numeric_limits :: max()。
给定两个整数操作数和总是从整数操作数(例如+或*,但不是/)产生整数的操作,所有IEEE 754舍入模式都将产生一个整数。如果此整数可以在int中表示(因此是在double中精确表示,假设其尾数至少与int一样宽),则它将是使用相应整数操作得到的相同整数。任何明智的FP实现都将保留以上保证,即使它不符合IEEE 754。

3

是的。所有的N位整数都可以用浮点表示法来表示,至少需要 N-1 位尾数(因为不需要存储隐式的前导1位),以及指数可以存储至少N,即具有log(N)+1位。

因此,你可以使用31位尾数、5位指数和1个符号位在浮点值中存储一个int32_t,它适合于典型的double,但不适合于float。反过来,只有24位尾数的float只能精确存储最高25位的int,即+/-33,554,431。


单精度浮点数有23个显式位(因此可以表示所有具有最多24位而不是25位的整数)。 - Stephen Canon
关于前导1位和需要足够大的指数的好处,这是一个很好的观点。虽然很难想象一个带有比log(bits(mantissa))更少的位数(指数)的FP实现,但具体说明这些事情是值得的! - j_random_hacker
Stephen 对于我的 float 数据类型的范围存在偏差的指出是正确的。所以有效范围是+/-16,777,215。 - pndc

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接