将双倍增加到下一个最接近的值?
这不是一个现实项目中的问题;而是一个问题。我只是好奇。
我们可以使用增量运算符 (i++
) 来增加 int
的值。您可以将此操作定义为:
这会增加与i
最接近的变量。在这种情况下就是+1。
但我正在考虑根据 IEEE 754-2008 系统定义特定范围内可用的双精度值的数量。我将能够建立一个图表来显示这些数量在某些范围内,并看看它是如何减少的。
我想应该有一种按位方式将双精度数增加到大于原始双精度数的最接近值。
我在维基百科上发现的是:
双精度示例
<前><代码>0x 3ff0 0000 0000 0000 = 1 0x 3ff0 0000 0000 0001 = 1.0000000000000002,下一个更高的数字> 1 0x 3ff0 0000 0000 0002 = 1.0000000000000004
在这里,您可以看到下一个更高的数字是通过增加二进制内容获得的。但我不认为这会继续有效,因为双重方案看起来像这样:
我认为有些东西当所有小数位都设置为一时,应该执行 else 以使增加最小。
也许这个操作有一个名字?有趣的参考资料?
欢迎任何信息:D
谢谢
This isn't a question for a real-life project; I'm only curious.
We can increase an int
using the increment operator (i++
). You can define this operation as:
This increases the variable with the closest value to i
. Which is in this case simply +1.
But I was thinking of defining the number of double values available in a specific range according the IEEE 754-2008 system. I would be able to set up a graph which demonstrates these amounts in some ranges and see how it is decreasing.
I guess there should be a bitwise way of increasing a double to the closest value greater than the original double.
What I found on Wikipedia is this:
Double precision examples
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
Here, you can see that the next higher number is obtained by increasing the binary content. But I don't think that this will keep working since the double scheme looks like this:
I think something else should be performed to make the smallest increase when all the fraction bits are set to one.
Maybe this operation has a name? Interesting references?
Any information is welcome :D
Thanks
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
初步估计,是的,这确实有效。
考虑一个标准化正数:这是一个值 m * 2e,其中 1 <= m < 2 ,即 m =
1.xxxxxxx
(二进制)。存储的值中省略了二进制小数点之前的“1
”,因此存储值的“小数”(或“尾数”或“有效数”)部分由二进制小数点之后的位组成。假设小数部分只有 4 位,而不是 52 位:存储值
1111
(二进制)在小数部分中表示 m =1.1111< /代码>(二进制)。将其视为整数并递增它会给出带有进位的
0000
的小数部分。但进位进入指数,从而使指数递增。完全正确:在
1.1111
* 2e 之后,我们期望的下一个数字是10.0000
,这确实是1.0000
* 2e+1 !我说“到第一个近似值”......将表示形式转换为整数,递增,然后转换回双精度数,对于正标准化数字确实很有效。它也适用于正非规格化数(小于最小规格化数;这些数字的指数为 0,并且通常隐藏的位是显式的)。
如果您的整数表示也是符号数值,则它适用于负数;但通常不会。对于更典型的二进制补码,您必须减一以“增加”负双精度数。
最后,最终您将溢出最大的归一化数并将指数增加到无穷大和 NaN 范围。
此处有一篇有趣的文章介绍了这一点。
To a first approximation, yes, this does work.
Consider a normalised positive number: this is a value m * 2e where 1 <= m < 2 , i.e. m =
1.xxxxxxx
(in binary) . The "1
" before the binary point is omitted in the stored value, so the "fraction" (or "mantissa" or "significand") part of the stored value consists of the bits after the binary point.Let's imagine that there are only 4 bits in the fraction part, rather than 52: the stored value
1111
(binary) represents in the fraction part m =1.1111
(binary). Treating this as an integer and incrementing it gives a fraction part of0000
with a carry.But the carry goes into the exponent, which increments it. That's exactly right: after
1.1111
* 2e, the next number we expect is10.0000
, which is indeed1.0000
* 2e+1 !I said "to a first approximation"... converting the representation to an integer, incrementing, and converting back to a double, does work nicely for positive normalised numbers. It also works for positive denormalised numbers (smaller than the smallest normalised number; these have an exponent of 0 and the bit which is usually hidden is explicit).
It works for negative numbers if your integer representation is also sign-magnitude; which it usually won't be. For the more typical two's complement, you have to subtract one to "increment" a negative double.
Finally, eventually you will overflow the largest normalised number and increment the exponent into the infinity and NaN range.
There is an interesting article which covers this here.
在 C99 中有 nextafter(3) 和朋友们。
如果您想手动完成,我认为最直接的方法是用一个整数表示有效数,用一个整数表示指数。
如果您要避免次正态并增加正数,则当显着性达到 2<<52 时,您应该增加指数并将显着性除以 2。
In C99 there are nextafter(3) and friends.
If you wish to do it by hand, I think it is most straight forward to have one integer to represent the significand and one for the exponent.
If you are avoiding subnormals and incrementing positive numbers, when the significant reaches 2<<52 you should increase the exponent and divide the significant by 2.