sis-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From desruisse...@apache.org
Subject svn commit: r1528121 - in /sis/branches/JDK7/core/sis-utility/src: main/java/org/apache/sis/internal/util/DoubleDouble.java test/java/org/apache/sis/internal/util/DoubleDoubleTest.java
Date Tue, 01 Oct 2013 15:40:01 GMT
Author: desruisseaux
Date: Tue Oct  1 15:40:01 2013
New Revision: 1528121

URL: http://svn.apache.org/r1528121
Log:
Adds a few constants for double-double arithmetic, especially for values related to PI and
conversions between degrees and radians.

Modified:
    sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/internal/util/DoubleDouble.java
    sis/branches/JDK7/core/sis-utility/src/test/java/org/apache/sis/internal/util/DoubleDoubleTest.java

Modified: sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/internal/util/DoubleDouble.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/internal/util/DoubleDouble.java?rev=1528121&r1=1528120&r2=1528121&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/internal/util/DoubleDouble.java
[UTF-8] (original)
+++ sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/internal/util/DoubleDouble.java
[UTF-8] Tue Oct  1 15:40:01 2013
@@ -101,14 +101,33 @@ public final class DoubleDouble extends 
      * For any value at index <var>i</var>, the associated error is {@code ERRORS[i]}.
      */
     private static final double[] VALUES = {
-        0.000001,
-        0.00001,
-        0.0001,
-        0.001,
-        0.01,
-        0.1,
-        0.3048,     // Feet to metres
-        0.9         // Degrees to gradians
+        // Some of the following constants have more fraction digits than necessary. We declare
the extra
+        // digits for documentation purpose, and in order to have identical content than
DoubleDoubleTest
+        // so that a plain copy-and-paste can be performed between those two classes.
+         0.000001,
+         0.00001,
+         0.0001,
+         0.00027777777777777777777777777777777778,  // Second to degrees
+         0.001,
+         0.002777777777777777777777777777777778,    // 1/360°
+         0.01,
+         0.01666666666666666666666666666666667,     // Minute to degrees
+         0.017453292519943295769236907684886127134428333, // Degrees to radians
+         0.1,
+         0.201168,                                  // Link to metres
+         0.3048,                                    // Feet to metres
+         0.785398163397448309615660845819876,       // π/4
+         0.9,                                       // Degrees to gradians
+         0.9144,                                    // Yard to metres
+         1.111111111111111111111111111111111,       // Gradian to degrees
+         1.570796326794896619231321691639751,       // π/2
+         1.8288,                                    // Fathom to metres
+         2.356194490192344928846982537459627,       // π * 3/4
+         2.54,                                      // Inch to centimetres
+         3.14159265358979323846264338327950,        // π
+         6.28318530717958647692528676655901,        // 2π
+        20.1168,                                    // Chain to metres
+        57.2957795130823208767981548141052          // Radians to degrees
     };
 
     /**
@@ -124,14 +143,30 @@ public final class DoubleDouble extends 
      * </ul>
      */
     private static final double[] ERRORS = {
-        /* 0.000001  */  4.525188817411374E-23,
-        /* 0.00001   */ -8.180305391403131E-22,
-        /* 0.0001    */ -4.79217360238593E-21,
-        /* 0.001     */ -2.0816681711721686E-20,
-        /* 0.01      */ -2.0816681711721684E-19,
-        /* 0.1       */ -5.551115123125783E-18,
-        /* 0.3048    */ -1.5365486660812166E-17,
-        /* 0.9       */ -2.2204460492503132E-17
+        /*  0.000001  */  4.525188817411374E-23,
+        /*  0.00001   */ -8.180305391403131E-22,
+        /*  0.0001    */ -4.79217360238593E-21,
+        /*  0.000266… */  2.4093381610788987E-22,
+        /*  0.001     */ -2.0816681711721686E-20,
+        /*  0.002666… */ -1.0601087908747154E-19,
+        /*  0.01      */ -2.0816681711721684E-19,
+        /*  0.016666… */  2.312964634635743E-19,
+        /*  0.017453… */  2.9486522708701687E-19,
+        /*  0.1       */ -5.551115123125783E-18,
+        /*  0.201168  */ -1.3471890270011499E-17,
+        /*  0.3048    */ -1.5365486660812166E-17,
+        /*  0.785398… */  3.061616997868383E-17,
+        /*  0.9       */ -2.2204460492503132E-17,
+        /*  0.9144    */  9.414691248821328E-18,
+        /*  1.111111… */ -4.9343245538895844E-17,
+        /*  1.570796… */  6.123233995736766E-17,
+        /*  1.8288    */  1.8829382497642655E-17,
+        /*  2.356194… */  9.184850993605148E-17,
+        /*  2.54      */ -3.552713678800501E-17,
+        /*  3.141592… */  1.2246467991473532E-16,
+        /*  6.283185… */  2.4492935982947064E-16,
+        /* 20.1168    */ -1.3471890270011499E-15,
+        /* 57.295779… */ -1.9878495670576283E-15
     };
 
     /**

Modified: sis/branches/JDK7/core/sis-utility/src/test/java/org/apache/sis/internal/util/DoubleDoubleTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-utility/src/test/java/org/apache/sis/internal/util/DoubleDoubleTest.java?rev=1528121&r1=1528120&r2=1528121&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-utility/src/test/java/org/apache/sis/internal/util/DoubleDoubleTest.java
[UTF-8] (original)
+++ sis/branches/JDK7/core/sis-utility/src/test/java/org/apache/sis/internal/util/DoubleDoubleTest.java
[UTF-8] Tue Oct  1 15:40:01 2013
@@ -42,9 +42,9 @@ import static java.lang.StrictMath.*;
 @DependsOn(org.apache.sis.math.MathFunctionsTest.class)
 public final strictfp class DoubleDoubleTest extends TestCase {
     /**
-     * Number of iterations in each test method.
+     * Number of time to repeat arithmetic tests.
      */
-    private static final int NUM_ITERATIONS = 1000;
+    private static final int NUMBER_OF_REPETITIONS = 1000;
 
     /**
      * The tolerance factor (as a multiplicand) for the addition and subtraction operations.
@@ -59,6 +59,11 @@ public final strictfp class DoubleDouble
     private static final double PRODUCT_TOLERANCE_FACTOR = 10000;
 
     /**
+     * Tolerance threshold for strict comparisons of floating point values.
+     */
+    private static final double STRICT = 0;
+
+    /**
      * The random number generator to use for the test.
      */
     private final Random random = TestUtilities.createRandomNumberGenerator();
@@ -96,7 +101,7 @@ public final strictfp class DoubleDouble
      */
     private static void assertNormalizedAndEquals(final double expected, final DoubleDouble
actual) {
         assertTrue("DoubleDouble is not normalized.", abs(actual.error) <= ulp(actual.value));
-        assertEquals("Unexpected arithmetic result.", expected, actual.value, 0.0);
+        assertEquals("Unexpected arithmetic result.", expected, actual.value, STRICT);
     }
 
     /**
@@ -128,7 +133,7 @@ public final strictfp class DoubleDouble
     @DependsOnMethod("testSetToQuickSum")
     public void testNormalize() {
         final DoubleDouble dd = new DoubleDouble();
-        for (int i=0; i<NUM_ITERATIONS; i++) {
+        for (int i=0; i<NUMBER_OF_REPETITIONS; i++) {
             double a = nextRandom();
             double b = nextRandom();
             if (abs(a) < abs(b)) {
@@ -150,7 +155,7 @@ public final strictfp class DoubleDouble
     @Test
     public void testSetToQuickSum() {
         final DoubleDouble dd = new DoubleDouble();
-        for (int i=0; i<NUM_ITERATIONS; i++) {
+        for (int i=0; i<NUMBER_OF_REPETITIONS; i++) {
             double a = nextRandom();
             double b = nextRandom();
             if (abs(a) < abs(b)) {
@@ -170,7 +175,7 @@ public final strictfp class DoubleDouble
     @Test
     public void testSetToSum() {
         final DoubleDouble dd = new DoubleDouble();
-        for (int i=0; i<NUM_ITERATIONS; i++) {
+        for (int i=0; i<NUMBER_OF_REPETITIONS; i++) {
             final double a = nextRandom();
             final double b = nextRandom();
             dd.setToSum(a, b);
@@ -185,7 +190,7 @@ public final strictfp class DoubleDouble
     @Test
     public void testSetToProduct() {
         final DoubleDouble dd = new DoubleDouble();
-        for (int i=0; i<NUM_ITERATIONS; i++) {
+        for (int i=0; i<NUMBER_OF_REPETITIONS; i++) {
             final double a = nextRandom();
             final double b = nextRandom();
             dd.setToProduct(a, b);
@@ -202,7 +207,7 @@ public final strictfp class DoubleDouble
     public void testAdd() {
         final DoubleDouble dd = new DoubleDouble();
         final DoubleDouble op = new DoubleDouble();
-        for (int i=0; i<NUM_ITERATIONS; i++) {
+        for (int i=0; i<NUMBER_OF_REPETITIONS; i++) {
             nextRandom(dd);
             nextRandom(op);
             final BigDecimal expected = toBigDecimal(dd).add(toBigDecimal(op));
@@ -219,7 +224,7 @@ public final strictfp class DoubleDouble
     public void testMultiply() {
         final DoubleDouble dd = new DoubleDouble();
         final DoubleDouble op = new DoubleDouble();
-        for (int i=0; i<NUM_ITERATIONS; i++) {
+        for (int i=0; i<NUMBER_OF_REPETITIONS; i++) {
             nextRandom(dd);
             nextRandom(op);
             final BigDecimal expected = toBigDecimal(dd).multiply(toBigDecimal(op), MathContext.DECIMAL128);
@@ -236,7 +241,7 @@ public final strictfp class DoubleDouble
     public void testDivide() {
         final DoubleDouble dd = new DoubleDouble();
         final DoubleDouble op = new DoubleDouble();
-        for (int i=0; i<NUM_ITERATIONS; i++) {
+        for (int i=0; i<NUMBER_OF_REPETITIONS; i++) {
             nextRandom(dd);
             nextRandom(op);
             final BigDecimal expected = toBigDecimal(dd).divide(toBigDecimal(op), MathContext.DECIMAL128);
@@ -249,14 +254,30 @@ public final strictfp class DoubleDouble
      * List of all {@link DoubleDouble#VALUES} as string decimal representation.
      */
     private static final String[] PREDEFINED_VALUES = {
-        "0.000001",
-        "0.00001",
-        "0.0001",
-        "0.001",
-        "0.01",
-        "0.1",
-        "0.3048",
-        "0.9"
+         "0.000001",
+         "0.00001",
+         "0.0001",
+         "0.00027777777777777777777777777777777778",
+         "0.001",
+         "0.002777777777777777777777777777777778",
+         "0.01",
+         "0.01666666666666666666666666666666667",
+         "0.017453292519943295769236907684886127134428333",
+         "0.1",
+         "0.201168",
+         "0.3048",
+         "0.785398163397448309615660845819876",
+         "0.9",
+         "0.9144",
+         "1.111111111111111111111111111111111",
+         "1.570796326794896619231321691639751",
+         "1.8288",
+         "2.356194490192344928846982537459627",
+         "2.54",
+         "3.14159265358979323846264338327950",
+         "6.28318530717958647692528676655901",
+        "20.1168",
+        "57.2957795130823208767981548141052"
     };
 
     /**
@@ -290,9 +311,35 @@ public final strictfp class DoubleDouble
             final BigDecimal accurate      = new BigDecimal(text);
             final BigDecimal approximation = new BigDecimal(value);
             final double     expected      = accurate.subtract(approximation).doubleValue();
-            assertEquals(text,  expected, DoubleDouble.errorForWellKnownValue( value), 0);
-            assertEquals(text, -expected, DoubleDouble.errorForWellKnownValue(-value), 0);
+            assertEquals(text,  expected, DoubleDouble.errorForWellKnownValue( value), STRICT);
+            assertEquals(text, -expected, DoubleDouble.errorForWellKnownValue(-value), STRICT);
             assertFalse("There is no point to define an entry for values having no error.",
expected == 0);
         }
     }
+
+    /**
+     * Tests π values using the {@link Math#PI} constant.
+     * This test method serves two purposes:
+     *
+     * <ul>
+     *   <li>Ensure that the results of small arithmetic operations on {@link Math#PI}
produce
+     *       numbers that {@link DoubleDouble#errorForWellKnownValue(double)} can find.</li>
+     *   <li>Compare with the values computed by the {@code qd-2.3.14} package (a C/C++
library),
+     *       which is taken as the reference implementation.</li>
+     * </ul>
+     */
+    @Test
+    @DependsOnMethod("testErrorForWellKnownValue")
+    public void testPI() {
+        assertEquals(1.224646799147353207E-16, DoubleDouble.errorForWellKnownValue(PI   
), STRICT);
+        assertEquals(2.449293598294706414E-16, DoubleDouble.errorForWellKnownValue(PI * 2),
STRICT);
+        assertEquals(6.123233995736766036E-17, DoubleDouble.errorForWellKnownValue(PI / 2),
STRICT);
+        assertEquals(3.061616997868383018E-17, DoubleDouble.errorForWellKnownValue(PI / 4),
STRICT);
+        assertEquals(9.184850993605148436E-17, DoubleDouble.errorForWellKnownValue(PI * (3./4)),
STRICT);
+
+        assertTrue("toDegrees", DoubleDouble.errorForWellKnownValue(180 / PI)     != 0);
+        assertTrue("toDegrees", DoubleDouble.errorForWellKnownValue(toDegrees(1)) != 0);
+        assertTrue("toRadians", DoubleDouble.errorForWellKnownValue(PI / 180)     != 0);
+        assertTrue("toRadians", DoubleDouble.errorForWellKnownValue(toRadians(1)) != 0);
+    }
 }



Mime
View raw message