You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by se...@apache.org on 2011/02/12 19:27:22 UTC
svn commit: r1070122 - in /commons/proper/math/branches/MATH_2_X/src:
main/java/org/apache/commons/math/util/MathUtils.java
test/java/org/apache/commons/math/util/MathUtilsTest.java
Author: sebb
Date: Sat Feb 12 18:27:22 2011
New Revision: 1070122
URL: http://svn.apache.org/viewvc?rev=1070122&view=rev
Log:
Revert MathUtils to 2.1 behaviour.
Update tests accordingly, and restore missing tests from 2.1 version
Note: removed deprecation from methods that merely change behaviour in 3.0
Modified:
commons/proper/math/branches/MATH_2_X/src/main/java/org/apache/commons/math/util/MathUtils.java
commons/proper/math/branches/MATH_2_X/src/test/java/org/apache/commons/math/util/MathUtilsTest.java
Modified: commons/proper/math/branches/MATH_2_X/src/main/java/org/apache/commons/math/util/MathUtils.java
URL: http://svn.apache.org/viewvc/commons/proper/math/branches/MATH_2_X/src/main/java/org/apache/commons/math/util/MathUtils.java?rev=1070122&r1=1070121&r2=1070122&view=diff
==============================================================================
--- commons/proper/math/branches/MATH_2_X/src/main/java/org/apache/commons/math/util/MathUtils.java (original)
+++ commons/proper/math/branches/MATH_2_X/src/main/java/org/apache/commons/math/util/MathUtils.java Sat Feb 12 18:27:22 2011
@@ -530,7 +530,7 @@ public final class MathUtils {
* @deprecated This method considers that {@code NaN == NaN}. In release
* 3.0, the semantics will change in order to comply with IEEE754 where it
* is specified that {@code NaN != NaN}.
- * New methods have been added for those cases wher the old semantics is
+ * New methods have been added for those cases where the old semantics is
* useful (see e.g. {@link #equalsIncludingNaN(float[],float[])
* equalsIncludingNaN}.
*/
@@ -576,21 +576,22 @@ public final class MathUtils {
}
/**
- * Returns true iff they are strictly equal.
+ * Returns true iff both arguments are NaN or neither is NaN and they are
+ * equal
*
- * @param x first value
- * @param y second value
- * @return {@code true} if the values are equal.
- * @deprecated This method considers that {@code NaN == NaN}. In release
+ * <p>This method considers that {@code NaN == NaN}. In release
* 3.0, the semantics will change in order to comply with IEEE754 where it
- * is specified that {@code NaN != NaN}. Also, two adjacent floating point
- * numbers will be considered equal.
+ * is specified that {@code NaN != NaN}.
* New methods have been added for those cases where the old semantics
* (w.r.t. NaN) is useful (see e.g.
- * {@link #equalsIncludingNaN(double,double) equalsIncludingNaN}.
+ * {@link #equalsIncludingNaN(double,double, double) equalsIncludingNaN}.
+ * </p>
+ *
+ * @param x first value
+ * @param y second value
+ * @return {@code true} if the values are equal.
*/
- @Deprecated
- public static boolean equals(double x, double y) {
+ public static boolean equals(double x, double y) {
return (Double.isNaN(x) && Double.isNaN(y)) || x == y;
}
@@ -609,14 +610,23 @@ public final class MathUtils {
/**
* Returns true if both arguments are equal or within the range of allowed
* error (inclusive).
- *
+ * <p>
+ * Two NaNs are considered equals, as are two infinities with same sign.
+ * </p>
+ * <p>This method considers that {@code NaN == NaN}. In release
+ * 3.0, the semantics will change in order to comply with IEEE754 where it
+ * is specified that {@code NaN != NaN}.
+ * New methods have been added for those cases where the old semantics
+ * (w.r.t. NaN) is useful (see e.g.
+ * {@link #equalsIncludingNaN(double,double, double) equalsIncludingNaN}.
+ * </p>
* @param x first value
* @param y second value
* @param eps the amount of absolute error to allow.
* @return {@code true} if the values are equal or within range of each other.
*/
public static boolean equals(double x, double y, double eps) {
- return equals(x, y, 1) || FastMath.abs(y - x) <= eps;
+ return equals(x, y) || FastMath.abs(y - x) <= eps;
}
/**
@@ -643,6 +653,14 @@ public final class MathUtils {
* href="http://www.cygnus-software.com/papers/comparingfloats/comparingfloats.htm">
* Bruce Dawson</a>
*
+ * <p>This method considers that {@code NaN == NaN}. In release
+ * 3.0, the semantics will change in order to comply with IEEE754 where it
+ * is specified that {@code NaN != NaN}.
+ * New methods have been added for those cases where the old semantics
+ * (w.r.t. NaN) is useful (see e.g.
+ * {@link #equalsIncludingNaN(double,double, int) equalsIncludingNaN}.
+ * </p>
+ *
* @param x first value
* @param y second value
* @param maxUlps {@code (maxUlps - 1)} is the number of floating point
@@ -666,9 +684,7 @@ public final class MathUtils {
yInt = SGN_MASK - yInt;
}
- final boolean isEqual = FastMath.abs(xInt - yInt) <= maxUlps;
-
- return isEqual && !Double.isNaN(x) && !Double.isNaN(y);
+ return FastMath.abs(xInt - yInt) <= maxUlps;
}
/**
@@ -691,18 +707,18 @@ public final class MathUtils {
* their elements are equal as defined by
* {@link #equals(double,double)}.
*
- * @param x first array
- * @param y second array
- * @return true if the values are both null or have same dimension
- * and equal elements.
- * @deprecated This method considers that {@code NaN == NaN}. In release
+ * <p>This method considers that {@code NaN == NaN}. In release
* 3.0, the semantics will change in order to comply with IEEE754 where it
* is specified that {@code NaN != NaN}.
* New methods have been added for those cases wher the old semantics is
* useful (see e.g. {@link #equalsIncludingNaN(double[],double[])
* equalsIncludingNaN}.
+ * </p>
+ * @param x first array
+ * @param y second array
+ * @return true if the values are both null or have same dimension
+ * and equal elements.
*/
- @Deprecated
public static boolean equals(double[] x, double[] y) {
if ((x == null) || (y == null)) {
return !((x == null) ^ (y == null));
@@ -1290,10 +1306,46 @@ public final class MathUtils {
* @return the next machine representable number in the specified direction
* @since 1.2
* @deprecated as of 2.2, replaced by {@link FastMath#nextAfter(double, double)}
+ * which handles Infinities differently, and returns direction if d and direction compare equal.
*/
@Deprecated
public static double nextAfter(double d, double direction) {
- return FastMath.nextAfter(d, direction);
+
+ // handling of some important special cases
+ if (Double.isNaN(d) || Double.isInfinite(d)) {
+ return d;
+ } else if (d == 0) {
+ return (direction < 0) ? -Double.MIN_VALUE : Double.MIN_VALUE;
+ }
+ // special cases MAX_VALUE to infinity and MIN_VALUE to 0
+ // are handled just as normal numbers
+
+ // split the double in raw components
+ long bits = Double.doubleToLongBits(d);
+ long sign = bits & 0x8000000000000000L;
+ long exponent = bits & 0x7ff0000000000000L;
+ long mantissa = bits & 0x000fffffffffffffL;
+
+ if (d * (direction - d) >= 0) {
+ // we should increase the mantissa
+ if (mantissa == 0x000fffffffffffffL) {
+ return Double.longBitsToDouble(sign |
+ (exponent + 0x0010000000000000L));
+ } else {
+ return Double.longBitsToDouble(sign |
+ exponent | (mantissa + 1));
+ }
+ } else {
+ // we should decrease the mantissa
+ if (mantissa == 0L) {
+ return Double.longBitsToDouble(sign |
+ (exponent - 0x0010000000000000L) |
+ 0x000fffffffffffffL);
+ } else {
+ return Double.longBitsToDouble(sign |
+ exponent | (mantissa - 1));
+ }
+ }
}
/**
Modified: commons/proper/math/branches/MATH_2_X/src/test/java/org/apache/commons/math/util/MathUtilsTest.java
URL: http://svn.apache.org/viewvc/commons/proper/math/branches/MATH_2_X/src/test/java/org/apache/commons/math/util/MathUtilsTest.java?rev=1070122&r1=1070121&r2=1070122&view=diff
==============================================================================
--- commons/proper/math/branches/MATH_2_X/src/test/java/org/apache/commons/math/util/MathUtilsTest.java (original)
+++ commons/proper/math/branches/MATH_2_X/src/test/java/org/apache/commons/math/util/MathUtilsTest.java Sat Feb 12 18:27:22 2011
@@ -315,6 +315,26 @@ public final class MathUtilsTest extends
assertTrue(Double.isNaN(MathUtils.cosh(Double.NaN)));
}
+ public void testEquals() {
+ double[] testArray = {
+ Double.NaN,
+ Double.POSITIVE_INFINITY,
+ Double.NEGATIVE_INFINITY,
+ 1d,
+ 0d };
+ for (int i = 0; i < testArray.length; i++) {
+ for (int j = 0; j < testArray.length; j++) {
+ if (i == j) {
+ assertTrue(MathUtils.equals(testArray[i], testArray[j]));
+ assertTrue(MathUtils.equals(testArray[j], testArray[i]));
+ } else {
+ assertTrue(!MathUtils.equals(testArray[i], testArray[j]));
+ assertTrue(!MathUtils.equals(testArray[j], testArray[i]));
+ }
+ }
+ }
+ }
+
public void testEqualsIncludingNaN() {
double[] testArray = {
Double.NaN,
@@ -339,7 +359,7 @@ public final class MathUtilsTest extends
assertTrue(MathUtils.equals(153.0000, 153.0000, .0625));
assertTrue(MathUtils.equals(153.0000, 153.0625, .0625));
assertTrue(MathUtils.equals(152.9375, 153.0000, .0625));
- assertFalse(MathUtils.equals(Double.NaN, Double.NaN, 1.0));
+ assertTrue(MathUtils.equals(Double.NaN, Double.NaN, 1.0)); // This will change in 3.0
assertTrue(MathUtils.equals(Double.POSITIVE_INFINITY, Double.POSITIVE_INFINITY, 1.0));
assertTrue(MathUtils.equals(Double.NEGATIVE_INFINITY, Double.NEGATIVE_INFINITY, 1.0));
assertFalse(MathUtils.equals(Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY, 1.0));
@@ -394,6 +414,31 @@ public final class MathUtilsTest extends
assertFalse(MathUtils.equals(Float.NEGATIVE_INFINITY, Float.POSITIVE_INFINITY, 100000));
}
+ public void testEqualsWithAllowedUlps21() { // From 2.1
+ assertTrue(MathUtils.equals(153, 153, 1));
+
+ assertTrue(MathUtils.equals(153, 153.00000000000003, 1));
+ assertFalse(MathUtils.equals(153, 153.00000000000006, 1));
+ assertTrue(MathUtils.equals(153, 152.99999999999997, 1));
+ assertFalse(MathUtils.equals(153, 152.99999999999994, 1));
+
+ assertTrue(MathUtils.equals(-128, -127.99999999999999, 1));
+ assertFalse(MathUtils.equals(-128, -127.99999999999997, 1));
+ assertTrue(MathUtils.equals(-128, -128.00000000000003, 1));
+ assertFalse(MathUtils.equals(-128, -128.00000000000006, 1));
+
+ assertTrue(MathUtils.equals(Double.POSITIVE_INFINITY, Double.POSITIVE_INFINITY, 1));
+ assertTrue(MathUtils.equals(Double.MAX_VALUE, Double.POSITIVE_INFINITY, 1));
+
+ assertTrue(MathUtils.equals(Double.NEGATIVE_INFINITY, Double.NEGATIVE_INFINITY, 1));
+ assertTrue(MathUtils.equals(-Double.MAX_VALUE, Double.NEGATIVE_INFINITY, 1));
+
+
+ assertTrue(MathUtils.equals(Double.NaN, Double.NaN, 1));
+
+ assertFalse(MathUtils.equals(Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY, 100000));
+ }
+
public void testEqualsWithAllowedUlps() {
assertTrue(MathUtils.equals(0.0, -0.0, 1));
@@ -427,7 +472,7 @@ public final class MathUtilsTest extends
assertTrue(MathUtils.equals(Double.NEGATIVE_INFINITY, Double.NEGATIVE_INFINITY, 1));
assertTrue(MathUtils.equals(-Double.MAX_VALUE, Double.NEGATIVE_INFINITY, 1));
- assertFalse(MathUtils.equals(Double.NaN, Double.NaN, 1));
+ assertTrue(MathUtils.equals(Double.NaN, Double.NaN, 1)); // This will change in 3.0
assertFalse(MathUtils.equals(Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY, 100000));
}
@@ -957,6 +1002,91 @@ public final class MathUtilsTest extends
}
}
+ public void testNextAfter() { // Test from Math 2.1
+ // 0x402fffffffffffff 0x404123456789abcd -> 4030000000000000
+ assertEquals(16.0, MathUtils.nextAfter(15.999999999999998, 34.27555555555555), 0.0);
+
+ // 0xc02fffffffffffff 0x404123456789abcd -> c02ffffffffffffe
+ assertEquals(-15.999999999999996, MathUtils.nextAfter(-15.999999999999998, 34.27555555555555), 0.0);
+
+ // 0x402fffffffffffff 0x400123456789abcd -> 402ffffffffffffe
+ assertEquals(15.999999999999996, MathUtils.nextAfter(15.999999999999998, 2.142222222222222), 0.0);
+
+ // 0xc02fffffffffffff 0x400123456789abcd -> c02ffffffffffffe
+ assertEquals(-15.999999999999996, MathUtils.nextAfter(-15.999999999999998, 2.142222222222222), 0.0);
+
+ // 0x4020000000000000 0x404123456789abcd -> 4020000000000001
+ assertEquals(8.000000000000002, MathUtils.nextAfter(8.0, 34.27555555555555), 0.0);
+
+ // 0xc020000000000000 0x404123456789abcd -> c01fffffffffffff
+ assertEquals(-7.999999999999999, MathUtils.nextAfter(-8.0, 34.27555555555555), 0.0);
+
+ // 0x4020000000000000 0x400123456789abcd -> 401fffffffffffff
+ assertEquals(7.999999999999999, MathUtils.nextAfter(8.0, 2.142222222222222), 0.0);
+
+ // 0xc020000000000000 0x400123456789abcd -> c01fffffffffffff
+ assertEquals(-7.999999999999999, MathUtils.nextAfter(-8.0, 2.142222222222222), 0.0);
+
+ // 0x3f2e43753d36a223 0x3f2e43753d36a224 -> 3f2e43753d36a224
+ assertEquals(2.308922399667661E-4, MathUtils.nextAfter(2.3089223996676606E-4, 2.308922399667661E-4), 0.0);
+
+ // 0x3f2e43753d36a223 0x3f2e43753d36a223 -> 3f2e43753d36a224
+ assertEquals(2.308922399667661E-4, MathUtils.nextAfter(2.3089223996676606E-4, 2.3089223996676606E-4), 0.0);
+
+ // 0x3f2e43753d36a223 0x3f2e43753d36a222 -> 3f2e43753d36a222
+ assertEquals(2.3089223996676603E-4, MathUtils.nextAfter(2.3089223996676606E-4, 2.3089223996676603E-4), 0.0);
+
+ // 0x3f2e43753d36a223 0xbf2e43753d36a224 -> 3f2e43753d36a222
+ assertEquals(2.3089223996676603E-4, MathUtils.nextAfter(2.3089223996676606E-4, -2.308922399667661E-4), 0.0);
+
+ // 0x3f2e43753d36a223 0xbf2e43753d36a223 -> 3f2e43753d36a222
+ assertEquals(2.3089223996676603E-4, MathUtils.nextAfter(2.3089223996676606E-4, -2.3089223996676606E-4), 0.0);
+
+ // 0x3f2e43753d36a223 0xbf2e43753d36a222 -> 3f2e43753d36a222
+ assertEquals(2.3089223996676603E-4, MathUtils.nextAfter(2.3089223996676606E-4, -2.3089223996676603E-4), 0.0);
+
+ // 0xbf2e43753d36a223 0x3f2e43753d36a224 -> bf2e43753d36a222
+ assertEquals(-2.3089223996676603E-4, MathUtils.nextAfter(-2.3089223996676606E-4, 2.308922399667661E-4), 0.0);
+
+ // 0xbf2e43753d36a223 0x3f2e43753d36a223 -> bf2e43753d36a222
+ assertEquals(-2.3089223996676603E-4, MathUtils.nextAfter(-2.3089223996676606E-4, 2.3089223996676606E-4), 0.0);
+
+ // 0xbf2e43753d36a223 0x3f2e43753d36a222 -> bf2e43753d36a222
+ assertEquals(-2.3089223996676603E-4, MathUtils.nextAfter(-2.3089223996676606E-4, 2.3089223996676603E-4), 0.0);
+
+ // 0xbf2e43753d36a223 0xbf2e43753d36a224 -> bf2e43753d36a224
+ assertEquals(-2.308922399667661E-4, MathUtils.nextAfter(-2.3089223996676606E-4, -2.308922399667661E-4), 0.0);
+
+ // 0xbf2e43753d36a223 0xbf2e43753d36a223 -> bf2e43753d36a224
+ assertEquals(-2.308922399667661E-4, MathUtils.nextAfter(-2.3089223996676606E-4, -2.3089223996676606E-4), 0.0);
+
+ // 0xbf2e43753d36a223 0xbf2e43753d36a222 -> bf2e43753d36a222
+ assertEquals(-2.3089223996676603E-4, MathUtils.nextAfter(-2.3089223996676606E-4, -2.3089223996676603E-4), 0.0);
+
+ }
+
+ public void testNextAfterSpecialCases() {
+ assertTrue(Double.isInfinite(MathUtils.nextAfter(Double.NEGATIVE_INFINITY, 0)));
+ assertTrue(Double.isInfinite(MathUtils.nextAfter(Double.POSITIVE_INFINITY, 0)));
+ assertTrue(Double.isNaN(MathUtils.nextAfter(Double.NaN, 0)));
+ assertTrue(Double.isInfinite(MathUtils.nextAfter(Double.MAX_VALUE, Double.POSITIVE_INFINITY)));
+ assertTrue(Double.isInfinite(MathUtils.nextAfter(-Double.MAX_VALUE, Double.NEGATIVE_INFINITY)));
+ assertEquals(Double.MIN_VALUE, MathUtils.nextAfter(0, 1), 0);
+ assertEquals(-Double.MIN_VALUE, MathUtils.nextAfter(0, -1), 0);
+ assertEquals(0, MathUtils.nextAfter(Double.MIN_VALUE, -1), 0);
+ assertEquals(0, MathUtils.nextAfter(-Double.MIN_VALUE, 1), 0);
+ }
+
+ public void testScalb() { // Math 2.1
+ assertEquals( 0.0, MathUtils.scalb(0.0, 5), 1.0e-15);
+ assertEquals(32.0, MathUtils.scalb(1.0, 5), 1.0e-15);
+ assertEquals(1.0 / 32.0, MathUtils.scalb(1.0, -5), 1.0e-15);
+ assertEquals(Math.PI, MathUtils.scalb(Math.PI, 0), 1.0e-15);
+ assertTrue(Double.isInfinite(MathUtils.scalb(Double.POSITIVE_INFINITY, 1)));
+ assertTrue(Double.isInfinite(MathUtils.scalb(Double.NEGATIVE_INFINITY, 1)));
+ assertTrue(Double.isNaN(MathUtils.scalb(Double.NaN, 1)));
+ }
+
public void testNormalizeAngle() {
for (double a = -15.0; a <= 15.0; a += 0.1) {
for (double b = -15.0; b <= 15.0; b += 0.2) {
@@ -1436,6 +1566,38 @@ public final class MathUtilsTest extends
assertEquals(4, MathUtils.distanceInf(p1, p2));
}
+ public void testCheckOrder21() { // Test from 2.1
+ MathUtils.checkOrder(new double[] {-15, -5.5, -1, 2, 15}, 1, true);
+ MathUtils.checkOrder(new double[] {-15, -5.5, -1, 2, 2}, 1, false);
+ MathUtils.checkOrder(new double[] {3, -5.5, -11, -27.5}, -1, true);
+ MathUtils.checkOrder(new double[] {3, 0, 0, -5.5, -11, -27.5}, -1, false);
+
+ try {
+ MathUtils.checkOrder(new double[] {-15, -5.5, -1, -1, 2, 15}, 1, true);
+ fail("an exception should have been thrown");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+ try {
+ MathUtils.checkOrder(new double[] {-15, -5.5, -1, -2, 2}, 1, false);
+ fail("an exception should have been thrown");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+ try {
+ MathUtils.checkOrder(new double[] {3, 3, -5.5, -11, -27.5}, -1, true);
+ fail("an exception should have been thrown");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+ try {
+ MathUtils.checkOrder(new double[] {3, -1, 0, -5.5, -11, -27.5}, -1, false);
+ fail("an exception should have been thrown");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+ }
+
public void testCheckOrder() {
MathUtils.checkOrder(new double[] {-15, -5.5, -1, 2, 15},
MathUtils.OrderDirection.INCREASING, true);
Re: svn commit: r1070122 - in /commons/proper/math/branches/MATH_2_X/src:
main/java/org/apache/commons/math/util/MathUtils.java test/java/org/apache/commons/math/util/MathUtilsTest.java
Posted by sebb AT ASF <se...@apache.org>.
On 12 February 2011 18:27, <se...@apache.org> wrote:
> Author: sebb
> Date: Sat Feb 12 18:27:22 2011
> New Revision: 1070122
>
> URL: http://svn.apache.org/viewvc?rev=1070122&view=rev
> Log:
> Revert MathUtils to 2.1 behaviour.
> Update tests accordingly, and restore missing tests from 2.1 version
> Note: removed deprecation from methods that merely change behaviour in 3.0
It seemed wrong to deprecate a method that was not going to be
removed, but I won't veto restoring the deprecation if it is felt to
be more useful to do so.
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@commons.apache.org
For additional commands, e-mail: dev-help@commons.apache.org