对于浮点类型(float/double/long double)的任意值 'v',C89 是否保证 floor(v) 和 ceil(v) 的数学精确整数结果是 'v 类型的可表示值'?
任何后来的 C 或 C++ 标准都可以保证这一点吗?
IEEE 754 能保证这一点吗?
对于浮点类型(float/double/long double)的任意值 'v',C89 是否保证 floor(v) 和 ceil(v) 的数学精确整数结果是 'v 类型的可表示值'?
任何后来的 C 或 C++ 标准都可以保证这一点吗?
IEEE 754 能保证这一点吗?
这是由 IEEE-754 编号的构造来保证的。(要明确:C 不保证 IEEE-754,但以下分析适用于我熟悉的所有其他浮点格式;关键属性是格式中所有足够大的数字都是整数)。
回想一下,一个普通的 IEEE-754 数字的形式±1.xxx...xxx * 2^n
是 ,其中有效位字段(xxx...xxx
部分)的宽度由数字的类型定义(单精度为 23 个二进制位,双精度为 52 个二进制位)。n
在允许范围内具有指数 ( ) 的所有此类数字都是可表示的。
假设 WLOGv
是正数(如果v
是负数,我们可以交换ceil
并floor
在下面的分析中)。
让v
有k
有效位,并写出v
二进制定点数;有三种可能性:
情况 1:所有有效位都是整数。当我们写出来时v
,它看起来像这样
xxxxxxxxxxxxxxxxxxxxxxxx000000...00000.0
thenv
是一个整数,所以ceil(v) = floor(v) = v
,所以两者都是平凡可表示的。
情况 2:所有有效位都是小数。当我们写出来时v
,它看起来像
0.000000...00000xxxxxxxxxxxxxxxxxxxxxxxx
thenv
在 [0,1) 范围内,所以floor(v) = 0
是可表示的,并且ceil(v)
是零或一,两者都是可表示的。
情况 3:v
同时包含整数和小数有效位:
xxxxxxxxxxxxxx.xxxxxxxxxx
那么floor(v)
就是:
xxxxxxxxxxxxxx.
因为我们已经丢弃了至少一个小数位,floor(v)
最多有一个k-1
有效位,并且与 相同的指数v
,所以它是可表示的。
如果v
是整数,则ceil(v) = floor(v) = v
, soceil(v)
是可表示的。否则,ceil(v) = floor(v) + 1
, and so 也最多k-1
具有有效位并且也是可表示的。