JDK-8032016 : Optimizations of Math.next{After,Up}({float,double})
  • Type: Enhancement
  • Component: core-libs
  • Sub-Component: java.lang
  • Affected Version: 9
  • Priority: P4
  • Status: Resolved
  • Resolution: Fixed
  • Submitted: 2014-01-16
  • Updated: 2014-10-07
  • Resolved: 2014-05-02
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 9
9 b13Fixed
Related Reports
Relates :  
Description
For nextAfter(double,double) (same for float version), instead of testing NaN-ity right away,
we can test most common (or at least regular) cases first:

public static double nextAfter(double start, double direction) {
    // Balancing out by branching to going-down case first,
    // for it is heavier than going-up case (test if start is +-0.0).
    if (start > direction) {
        // Going down.
        if (start == 0.0d) {
            // start is +0.0 or -0.0
            return -Double.MIN_VALUE;
        }
        final long transducer = Double.doubleToRawLongBits(start);
        assert transducer != 0L;
        return Double.longBitsToDouble(transducer + ((transducer > 0L) ? -1L:1L));
    } else if (start < direction) {
        // Going up.
        // Add +0.0 to get rid of a -0.0 (+0.0 + -0.0 => +0.0)
        // then bitwise convert start to integer.
        final long transducer = Double.doubleToRawLongBits(start + 0.0d);
        return Double.longBitsToDouble(transducer + ((transducer >= 0L) ? 1L:-1L));
    } else if (start == direction) {
        return direction;
    } else { // start and/or direction is NaN
        return start + direction;
    }
}

Same for nextUp(double) and float version (also, testing transducer >= 0L
instead of d >= 0.0D seems to help):
public static double nextUp(double d) {
    if (d < Double.POSITIVE_INFINITY) {
        final long transducer = Double.doubleToRawLongBits(d + 0.0D);
        return Double.longBitsToDouble(transducer + ((transducer >= 0L) ? 1L:-1L));
    } else { // d is NaN or +Infinity
        return d;
    }
}

Reference: http://mail.openjdk.java.net/pipermail/core-libs-dev/2011-September/007708.html
Comments
Discussion thread: http://mail.openjdk.java.net/pipermail/core-libs-dev/2014-April/026686.html.
29-04-2014