Increase a double to the next closest value?

假如想象 提交于 2019-12-22 08:53:28

问题


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


回答1:


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:

[picture omitted]

I think something else should be performed to make the smallest increase when all the fraction bits are set to one.

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 of 0000 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 is 10.0000, which is indeed 1.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.




回答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.



来源:https://stackoverflow.com/questions/7288334/increase-a-double-to-the-next-closest-value

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!