You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@harmony.apache.org by te...@apache.org on 2007/06/13 15:34:38 UTC
svn commit: r546865 - in
/harmony/enhanced/classlib/branches/java6/modules/luni/src:
main/java/java/lang/Math.java
test/java/org/apache/harmony/luni/tests/java/lang/MathTest.java
Author: tellison
Date: Wed Jun 13 06:34:38 2007
New Revision: 546865
URL: http://svn.apache.org/viewvc?view=rev&rev=546865
Log:
Apply patch HARMONY-4137 ([classlib][luni][java6] new methods nextAfter, nextUp in java.lang.Math)
Modified:
harmony/enhanced/classlib/branches/java6/modules/luni/src/main/java/java/lang/Math.java
harmony/enhanced/classlib/branches/java6/modules/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/MathTest.java
Modified: harmony/enhanced/classlib/branches/java6/modules/luni/src/main/java/java/lang/Math.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/branches/java6/modules/luni/src/main/java/java/lang/Math.java?view=diff&rev=546865&r1=546864&r2=546865
==============================================================================
--- harmony/enhanced/classlib/branches/java6/modules/luni/src/main/java/java/lang/Math.java (original)
+++ harmony/enhanced/classlib/branches/java6/modules/luni/src/main/java/java/lang/Math.java Wed Jun 13 06:34:38 2007
@@ -715,4 +715,128 @@
bits = (bits & DOUBLE_EXPONENT_MASK) >> DOUBLE_MANTISSA_BITS;
return (int) bits - DOUBLE_EXPONENT_BIAS;
}
+
+ /**
+ * Answers a double next to the first given double value in the direction of
+ * the second given double.
+ *
+ * @param start
+ * the double value to start
+ * @param direction
+ * the double indicating the direction
+ * @return a double next to the first given double value in the direction of
+ * the second given double.
+ *
+ * @since 1.6
+ */
+ public static double nextAfter(double start, double direction) {
+ if (0 == start && 0 == direction) {
+ return direction;
+ }
+ return nextafter(start, direction);
+ }
+
+ /**
+ * Answers a float next to the first given float value in the direction of
+ * the second given double value.
+ *
+ * @param start
+ * the float value to start
+ * @param direction
+ * the double indicating the direction
+ * @return a float next to the first given float value in the direction of
+ * the second given double.
+ *
+ * @since 1.6
+ */
+ @SuppressWarnings("boxing")
+ public static float nextAfter(float start, double direction) {
+ if (Float.isNaN(start) || Double.isNaN(direction)) {
+ return Float.NaN;
+ }
+ if (0 == start && 0 == direction) {
+ return new Float(direction);
+ }
+ if ((start == Float.MIN_VALUE && direction < start)
+ || (start == -Float.MIN_VALUE && direction > start)) {
+ return (start > 0 ? 0f : -0f);
+ }
+ if (Float.isInfinite(start) && (direction != start)) {
+ return (start > 0 ? Float.MAX_VALUE : -Float.MAX_VALUE);
+ }
+ if ((start == Float.MAX_VALUE && direction > start)
+ || (start == -Float.MAX_VALUE && direction < start)) {
+ return (start > 0 ? Float.POSITIVE_INFINITY
+ : Float.NEGATIVE_INFINITY);
+ }
+ if (direction > start) {
+ if (start > 0) {
+ return Float.intBitsToFloat(Float.floatToIntBits(start) + 1);
+ }
+ if (start < 0) {
+ return Float.intBitsToFloat(Float.floatToIntBits(start) - 1);
+ }
+ return +Float.MIN_VALUE;
+ }
+ if (direction < start) {
+ if (start > 0) {
+ return Float.intBitsToFloat(Float.floatToIntBits(start) - 1);
+ }
+ if (start < 0) {
+ return Float.intBitsToFloat(Float.floatToIntBits(start) + 1);
+ }
+ return -Float.MIN_VALUE;
+ }
+ return new Float(direction);
+ }
+
+ /**
+ * Answers the next larger double value to d.
+ *
+ * @param d
+ * the double value to start
+ * @return the next larger double value of d.
+ *
+ * @since 1.6
+ */
+ public static double nextUp(double d) {
+ if (Double.isNaN(d)) {
+ return Double.NaN;
+ }
+ if ((d == Double.POSITIVE_INFINITY)) {
+ return Double.POSITIVE_INFINITY;
+ }
+ if (0 == d) {
+ return Double.MIN_VALUE;
+ } else if (0 < d) {
+ return Double.longBitsToDouble(Double.doubleToLongBits(d) + 1);
+ } else {
+ return Double.longBitsToDouble(Double.doubleToLongBits(d) - 1);
+ }
+ }
+
+ /**
+ * Answers the next larger float value to d.
+ *
+ * @param f
+ * the float value to start
+ * @return the next larger float value of d.
+ *
+ * @since 1.6
+ */
+ public static float nextUp(float f) {
+ if (Float.isNaN(f)) {
+ return Float.NaN;
+ }
+ if ((f == Float.POSITIVE_INFINITY)) {
+ return Float.POSITIVE_INFINITY;
+ }
+ if (0 == f) {
+ return Float.MIN_VALUE;
+ } else if (0 < f) {
+ return Float.intBitsToFloat(Float.floatToIntBits(f) + 1);
+ } else {
+ return Float.intBitsToFloat(Float.floatToIntBits(f) - 1);
+ }
+ }
}
Modified: harmony/enhanced/classlib/branches/java6/modules/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/MathTest.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/branches/java6/modules/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/MathTest.java?view=diff&rev=546865&r1=546864&r2=546865
==============================================================================
--- harmony/enhanced/classlib/branches/java6/modules/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/MathTest.java (original)
+++ harmony/enhanced/classlib/branches/java6/modules/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/MathTest.java Wed Jun 13 06:34:38 2007
@@ -702,6 +702,263 @@
assertEquals("Incorrect long min value",
-19088976000089L, Math.min(-20, -19088976000089L));
}
+
+ /**
+ * start number cases for test_nextAfter_DD in MathTest/StrictMathTest
+ * NEXTAFTER_DD_START_CASES[i][0] is the start number
+ * NEXTAFTER_DD_START_CASES[i][1] is the nextUp of start number
+ * NEXTAFTER_DD_START_CASES[i][2] is the nextDown of start number
+ */
+ static final double NEXTAFTER_DD_START_CASES[][] = new double[][] {
+ { 3.4, 3.4000000000000004, 3.3999999999999995 },
+ { -3.4, -3.3999999999999995, -3.4000000000000004 },
+ { 3.4233E109, 3.4233000000000005E109, 3.4232999999999996E109 },
+ { -3.4233E109, -3.4232999999999996E109, -3.4233000000000005E109 },
+ { +0.0, Double.MIN_VALUE, -Double.MIN_VALUE },
+ { 0.0, Double.MIN_VALUE, -Double.MIN_VALUE },
+ { -0.0, Double.MIN_VALUE, -Double.MIN_VALUE },
+ { Double.MIN_VALUE, 1.0E-323, +0.0 },
+ { -Double.MIN_VALUE, -0.0, -1.0E-323 },
+ { Double.MIN_NORMAL, 2.225073858507202E-308, 2.225073858507201E-308 },
+ { -Double.MIN_NORMAL, -2.225073858507201E-308,
+ -2.225073858507202E-308 },
+ { Double.MAX_VALUE, Double.POSITIVE_INFINITY,
+ 1.7976931348623155E308 },
+ { -Double.MAX_VALUE, -1.7976931348623155E308,
+ Double.NEGATIVE_INFINITY },
+ { Double.POSITIVE_INFINITY, Double.POSITIVE_INFINITY,
+ Double.MAX_VALUE },
+ { Double.NEGATIVE_INFINITY, -Double.MAX_VALUE,
+ Double.NEGATIVE_INFINITY } };
+
+ /**
+ * direction number cases for test_nextAfter_DD/test_nextAfter_FD in
+ * MathTest/StrictMathTest
+ */
+ static final double NEXTAFTER_DD_FD_DIRECTION_CASES[] = new double[] {
+ Double.POSITIVE_INFINITY, Double.MAX_VALUE, 8.8, 3.4, 1.4,
+ Double.MIN_NORMAL, Double.MIN_NORMAL / 2, Double.MIN_VALUE, +0.0,
+ 0.0, -0.0, -Double.MIN_VALUE, -Double.MIN_NORMAL / 2,
+ -Double.MIN_NORMAL, -1.4, -3.4, -8.8, -Double.MAX_VALUE,
+ Double.NEGATIVE_INFINITY };
+
+ /**
+ * @tests {@link java.lang.Math#nextAfter(double, double)}
+ * @since 1.6
+ */
+ @SuppressWarnings("boxing")
+ public void test_nextAfter_DD() {
+ // test for most cases without exception
+ for (int i = 0; i < NEXTAFTER_DD_START_CASES.length; i++) {
+ final double start = NEXTAFTER_DD_START_CASES[i][0];
+ final long nextUpBits = Double
+ .doubleToLongBits(NEXTAFTER_DD_START_CASES[i][1]);
+ final long nextDownBits = Double
+ .doubleToLongBits(NEXTAFTER_DD_START_CASES[i][2]);
+
+ for (int j = 0; j < NEXTAFTER_DD_FD_DIRECTION_CASES.length; j++) {
+ final double direction = NEXTAFTER_DD_FD_DIRECTION_CASES[j];
+ final long resultBits = Double.doubleToLongBits(Math.nextAfter(
+ start, direction));
+ final long directionBits = Double.doubleToLongBits(direction);
+ if (direction > start) {
+ assertEquals("Result should be next up-number.",
+ nextUpBits, resultBits);
+ } else if (direction < start) {
+ assertEquals("Result should be next down-number.",
+ nextDownBits, resultBits);
+ } else {
+ assertEquals("Result should be direction.", directionBits,
+ resultBits);
+ }
+ }
+ }
+
+ // test for cases with NaN
+ for (int i = 0; i < NEXTAFTER_DD_START_CASES.length; i++) {
+ assertTrue("The result should be NaN.", Double.isNaN(Math
+ .nextAfter(NEXTAFTER_DD_START_CASES[i][0], Double.NaN)));
+ }
+ for (int i = 0; i < NEXTAFTER_DD_FD_DIRECTION_CASES.length; i++) {
+ assertTrue("The result should be NaN.", Double.isNaN(Math
+ .nextAfter(Double.NaN, NEXTAFTER_DD_FD_DIRECTION_CASES[i])));
+ }
+ assertTrue("The result should be NaN.", Double.isNaN(Math.nextAfter(
+ Double.NaN, Double.NaN)));
+
+ // test for exception
+ try {
+ Math.nextAfter((Double) null, 2.3);
+ fail("Should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // Expected
+ }
+ try {
+ Math.nextAfter(2.3, (Double) null);
+ fail("Should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // Expected
+ }
+ try {
+ Math.nextAfter((Double) null, (Double) null);
+ fail("Should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // Expected
+ }
+ }
+
+ /**
+ * start number cases for test_nextAfter_FD in MathTest/StrictMathTest
+ * NEXTAFTER_FD_START_CASES[i][0] is the start number
+ * NEXTAFTER_FD_START_CASES[i][1] is the nextUp of start number
+ * NEXTAFTER_FD_START_CASES[i][2] is the nextDown of start number
+ */
+ static final float NEXTAFTER_FD_START_CASES[][] = new float[][] {
+ { 3.4f, 3.4000003f, 3.3999999f },
+ { -3.4f, -3.3999999f, -3.4000003f },
+ { 3.4233E19f, 3.4233002E19f, 3.4232998E19f },
+ { -3.4233E19f, -3.4232998E19f, -3.4233002E19f },
+ { +0.0f, Float.MIN_VALUE, -Float.MIN_VALUE },
+ { 0.0f, Float.MIN_VALUE, -Float.MIN_VALUE },
+ { -0.0f, Float.MIN_VALUE, -Float.MIN_VALUE },
+ { Float.MIN_VALUE, 2.8E-45f, +0.0f },
+ { -Float.MIN_VALUE, -0.0f, -2.8E-45f },
+ { Float.MIN_NORMAL, 1.1754945E-38f, 1.1754942E-38f },
+ { -Float.MIN_NORMAL, -1.1754942E-38f, -1.1754945E-38f },
+ { Float.MAX_VALUE, Float.POSITIVE_INFINITY, 3.4028233E38f },
+ { -Float.MAX_VALUE, -3.4028233E38f, Float.NEGATIVE_INFINITY },
+ { Float.POSITIVE_INFINITY, Float.POSITIVE_INFINITY, Float.MAX_VALUE },
+ { Float.NEGATIVE_INFINITY, -Float.MAX_VALUE,
+ Float.NEGATIVE_INFINITY } };
+
+ /**
+ * @tests {@link java.lang.Math#nextAfter(float, double)}
+ * @since 1.6
+ */
+ @SuppressWarnings("boxing")
+ public void test_nextAfter_FD() {
+ // test for most cases without exception
+ for (int i = 0; i < NEXTAFTER_FD_START_CASES.length; i++) {
+ final float start = NEXTAFTER_FD_START_CASES[i][0];
+ final int nextUpBits = Float
+ .floatToIntBits(NEXTAFTER_FD_START_CASES[i][1]);
+ final int nextDownBits = Float
+ .floatToIntBits(NEXTAFTER_FD_START_CASES[i][2]);
+
+ for (int j = 0; j < NEXTAFTER_DD_FD_DIRECTION_CASES.length; j++) {
+ final double direction = NEXTAFTER_DD_FD_DIRECTION_CASES[j];
+ final int resultBits = Float.floatToIntBits(Math.nextAfter(
+ start, direction));
+ if (direction > start) {
+ assertEquals("Result should be next up-number.",
+ nextUpBits, resultBits);
+ } else if (direction < start) {
+ assertEquals("Result should be next down-number.",
+ nextDownBits, resultBits);
+ } else {
+ final int equivalentBits = Float.floatToIntBits(new Float(
+ direction));
+ assertEquals(
+ "Result should be a number equivalent to direction.",
+ equivalentBits, resultBits);
+ }
+ }
+ }
+
+ // test for cases with NaN
+ for (int i = 0; i < NEXTAFTER_FD_START_CASES.length; i++) {
+ assertTrue("The result should be NaN.", Float.isNaN(Math.nextAfter(
+ NEXTAFTER_FD_START_CASES[i][0], Float.NaN)));
+ }
+ for (int i = 0; i < NEXTAFTER_DD_FD_DIRECTION_CASES.length; i++) {
+ assertTrue("The result should be NaN.", Float.isNaN(Math.nextAfter(
+ Float.NaN, NEXTAFTER_DD_FD_DIRECTION_CASES[i])));
+ }
+ assertTrue("The result should be NaN.", Float.isNaN(Math.nextAfter(
+ Float.NaN, Float.NaN)));
+
+ // test for exception
+ try {
+ Math.nextAfter((Float) null, 2.3);
+ fail("Should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // Expected
+ }
+ try {
+ Math.nextAfter(2.3, (Float) null);
+ fail("Should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // Expected
+ }
+ try {
+ Math.nextAfter((Float) null, (Float) null);
+ fail("Should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // Expected
+ }
+ }
+
+ /**
+ * @tests {@link java.lang.Math#nextUp(double)}
+ * @since 1.6
+ */
+ @SuppressWarnings("boxing")
+ public void test_nextUp_D() {
+ // This method is semantically equivalent to nextAfter(d,
+ // Double.POSITIVE_INFINITY),
+ // so we use the data of test_nextAfter_DD
+ for (int i = 0; i < NEXTAFTER_DD_START_CASES.length; i++) {
+ final double start = NEXTAFTER_DD_START_CASES[i][0];
+ final long nextUpBits = Double
+ .doubleToLongBits(NEXTAFTER_DD_START_CASES[i][1]);
+ final long resultBits = Double.doubleToLongBits(Math.nextUp(start));
+ assertEquals("Result should be next up-number.", nextUpBits,
+ resultBits);
+ }
+
+ // test for cases with NaN
+ assertTrue("The result should be NaN.", Double.isNaN(Math
+ .nextUp(Double.NaN)));
+
+ // test for exception
+ try {
+ Math.nextUp((Double) null);
+ fail("Should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // Expected
+ }
+ }
+
+ /**
+ * @tests {@link java.lang.Math#nextUp(float)}
+ * @since 1.6
+ */
+ @SuppressWarnings("boxing")
+ public void test_nextUp_F() {
+ // This method is semantically equivalent to nextAfter(f,
+ // Float.POSITIVE_INFINITY),
+ // so we use the data of test_nextAfter_FD
+ for (int i = 0; i < NEXTAFTER_FD_START_CASES.length; i++) {
+ final float start = NEXTAFTER_FD_START_CASES[i][0];
+ final int nextUpBits = Float
+ .floatToIntBits(NEXTAFTER_FD_START_CASES[i][1]);
+ final int resultBits = Float.floatToIntBits(Math.nextUp(start));
+ assertEquals("Result should be next up-number.", nextUpBits,
+ resultBits);
+ }
+
+ // test for cases with NaN
+ assertTrue("The result should be NaN.", Float.isNaN(Math
+ .nextUp(Float.NaN)));
+
+ // test for exception
+ try {
+ Math.nextUp((Float) null);
+ fail("Should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // Expected
+ }
+ }
/**
* @tests java.lang.Math#pow(double, double)