增加一倍到下一个最接近的值?

时间:2011-09-02 19:25:07

标签: floating-point bit-manipulation ieee-754

这不是现实生活中的问题;我只是很好奇。

我们可以使用增量运算符(int)增加i++。您可以将此操作定义为:
这会使变量与i 的值最接近。在这种情况下,这只是+1。

但我正在考虑根据IEEE 754-2008系统定义特定范围内可用的双值的数量。我可以设置一个图表,在某些范围内显示这些数量,并看看它是如何减少的。

我想应该有一种按比例的方式将double增加到最接近的值大于原来的double。

我在Wikipedia上找到的是:

  

双精度示例

0x 3ff0 0000 0000 0000   = 1
0x 3ff0 0000 0000 0001   = 1.0000000000000002, the next higher number > 1
0x 3ff0 0000 0000 0002   = 1.0000000000000004

在这里,您可以看到通过增加二进制内容获得下一个更高的数字。但我不认为这会继续有效,因为双重计划看起来像这样:

enter image description here

我认为当所有分数位设置为1时,应该执行其他操作以使增幅最小。

也许这个操作有名字?有趣的参考文献?
欢迎任何信息:D

由于

2 个答案:

答案 0 :(得分:4)

  

在这里,您可以看到通过增加二进制内容获得下一个更高的数字。但我不认为这会继续有效,因为双重计划看起来像这样:

     

[图片省略]

     

我认为当所有小数位都设置为1时,应该执行其他操作以使最小的增加。

首先,是的,这个 工作。

考虑归一化的正数:这是一个值 m * 2 e 其中1 <= m &lt; 2,即 m = 1.xxxxxxx(二进制)。在存储值中省略了二进制点之前的“1”,因此存储值的“分数”(或“尾数”或“有效数字”)部分由二进制点之后的位组成。

让我们假设小数部分只有4位,而不是52:存储值1111(二进制)代表小数部分 m = 1.1111 (二进制)。将其作为整数处理并递增它会给0000的一小部分带进位。

但是进位进入指数,它会增加它。这是完全正确的:在1.1111 * 2 e 之后,我们期望的下一个数字是10.0000,这确实是1.0000 * 2 e + 1 < / sup>!


我说“第一次近似”...将表示转换为整数,递增,然后转换回双精度,对于正标准化数字确实很有效。它也适用于正非规范化数字(小于最小规范化数字;它们的指数为0,通常隐藏的位是显式的)。

如果您的整数表示也是符号幅度,它适用于负数;它通常不会。对于更典型的二进制补码,您必须减去一个以“递增”负双。

最后,最终你会溢出最大的标准化数字,并将指数增加到无穷大和NaN范围。

有一篇有趣的文章涵盖了这个here

答案 1 :(得分:2)

在C99中有nextafter(3)和朋友。

如果您希望手动完成,我认为最简单的方法是使用一个整数来表示有效数,而将一个整数表示为指数。

如果你正在避免次正规并递增正数,当重要性达到2 <52时你应该增加指数并将显着性除以2.