开发者

How to alter a float by its smallest increment in Java?

I have a double value d and would like a way to nudge it very slightly larger (or smaller) to get a new value that will be as close as possible to the original but still strictly greater than (or less than) the original.

It doesn't have to be close down to the last bit—it's more important that whatever change I make is guaranteed to produce a different value and not round back to the original.

(This question has been asked and answered for C, C++)

The reason I need this, is that I'm mapping from Double to (something), and I may have multiple items with the save double 'value', but they all need to go individually into the map.

My current code (which does the job) looks like this:


private void putUniqueScoreIntoMap(TreeMap map, Double score,
            A entry) {

        int exponent = 15;
        while (map.containsKey(score)) {
            Doub开发者_如何学Cle newScore = score;
            while (newScore.equals(score) && exponent != 0) {
                newScore = score + (1.0d / (10 * exponent));
                exponent--;
            }
            if (exponent == 0) {
                throw new IllegalArgumentException("Failed to find unique new double value");
            }
            score = newScore;
        }
        map.put(score, entry);
    }


In Java 1.6 and later, the Math.nextAfter(double, double) method is the cleanest way to get the next double value after a given double value.

The second parameter is the direction that you want. Alternatively you can use Math.nextUp(double) (Java 1.6 and later) to get the next larger number and since Java 1.8 you can also use Math.nextDown(double) to get the next smaller number. These two methods are equivalent to using nextAfter with Positive or Negative infinity as the direction double.

Specifically, Math.nextAfter(score, Double.MAX_VALUE) will give you the answer in this case.


Use Double.doubleToRawLongBits and Double.longBitsToDouble:

double d = // your existing value;
long bits = Double.doubleToLongBits(d);
bits++;
d = Double.longBitsToDouble(bits);

The way IEEE-754 works, that will give you exactly the next viable double, i.e. the smallest amount greater than the existing value.

(Eventually it'll hit NaN and probably stay there, but it should work for sensible values.)


Have you considered using a data structure which would allow multiple values stored under the same key (e.g. a binary tree) instead of trying to hack the key value?


What about using Double.MIN_VALUE?


d += Double.MIN_VALUE

(or -= if you want to take away)


Use Double.MIN_VALUE.

The javadoc for it:

A constant holding the smallest positive nonzero value of type double, 2-1074. It is equal to the hexadecimal floating-point literal 0x0.0000000000001P-1022 and also equal to Double.longBitsToDouble(0x1L).

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜