-
Enhancement
-
Resolution: Fixed
-
P4
-
9
-
b13
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
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
- relates to
-
JDK-6667086 Double.doubleToLongBits(final double value) contains inefficient test for NaN
-
- Resolved
-