6

考虑 d1.d2d3d4d5...dnExxx 形式的十进制表示,其中 xxx 是任意指数,d1 和 dn 均非零。

是否已知最大 n 使得存在十进制表示 d1.d2d3d4d5...dnExxx 使得区间 (d1.d2d3d4d5...dnExxx, d1.d2d3d4d5...((dn)+1)Exxx) 包含 IEEE 754双?

n 至少应为 17。问题是 17 高多少。

这个数字 n 与在十进制到双精度转换中足以考虑的位数有关,例如strtod(). 我查看了David M. Gay 实现的源代码,希望在那里找到答案。有一个对“40”的暗示,但不清楚这是一个合理的数学结果的结果,还是只是一个统计上的安全界限。此外,关于“截断”的评论听起来像是 0.50000000000000000000000000000000000000000000000000001 在向上取整模式下可能会转换为 0.5。

Musl 的实现似乎读取了大约 125*9 个数字,这是很多的。然后它切换到“粘性”模式:

if (c!='0') x[KMAX-4] |= 1;

最后,将“包含一个 IEEE 754 双精度”替换为“包含两个连续 IEEE 754 双精度的中点”时,答案有何变化?

4

1 回答 1

6

当您有一个具有奇数有效位的次正规数时,即 的奇数倍2^(-1074),您有一个数字,其十进制表示中的最后一个非零数字是小数点后的第 1074 位。然后,小数点后面有大约 300 个零,因此该数字有大约 750-770 个有效十进制数字。最小的正次正规有 751 个有效数字,最大的正次正规有 767 个有效数字(我认为这是最大值)。2^(-1074)(2^52-1)*2^(-1074)

所以至少有一个d1, ..., d766十进制数字序列使得double在开区间中有一个 IEEE754

(d1.d2...d766E-308, d1.d2...(d766 + 1)E-308)

如果我们考虑“包含两个连续的 IEEE754 的中点”,答案不会有太大变化double,因为次正规double的 s 具有大致相同数量的有效十进制数字,并且两个连续的中点也是如此。

在最坏的情况下,必须消耗整个数字序列(考虑"0.5000000...0001"在最后一个 1 之前任意多个零,确定结果应该是0.5 + 0.5^53而不是0.5从零舍入或向上舍入时)。

然而,只有

floor(DBL_MANT_DIG * log 2 / log 10) + 2 = 17

区分不同double值所必需的有效十进制数字,因此一种相对简单但可能不是很有效的解析方法是将前(至少 17 个)数字(和指数)解析为最接近的double,并比较输入字符串具有该double值(及其邻居)的精确表示。

于 2013-06-21T22:54:35.300 回答