sis-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From desruisse...@apache.org
Subject svn commit: r1539609 - in /sis/branches/JDK7/core/sis-utility/src: main/java/org/apache/sis/math/ test/java/org/apache/sis/math/
Date Thu, 07 Nov 2013 12:21:48 GMT
Author: desruisseaux
Date: Thu Nov  7 12:21:48 2013
New Revision: 1539609

URL: http://svn.apache.org/r1539609
Log:
Added a test case for deltaForDoubleToDecimal

Modified:
    sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/math/DecimalFunctions.java
    sis/branches/JDK7/core/sis-utility/src/test/java/org/apache/sis/math/DecimalFunctionsTest.java
    sis/branches/JDK7/core/sis-utility/src/test/java/org/apache/sis/math/MathFunctionsTest.java
    sis/branches/JDK7/core/sis-utility/src/test/java/org/apache/sis/math/StatisticsTest.java

Modified: sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/math/DecimalFunctions.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/math/DecimalFunctions.java?rev=1539609&r1=1539608&r2=1539609&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/math/DecimalFunctions.java
[UTF-8] (original)
+++ sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/math/DecimalFunctions.java
[UTF-8] Thu Nov  7 12:21:48 2013
@@ -24,10 +24,25 @@ import static org.apache.sis.internal.ut
 
 
 /**
- * Functions working of {@code float} and {@code double} values while taking in account the
representation in base 10.
- * Methods in this class may be helpful when used immediately after parsing (i.e. before
any calculations are applied
- * on the value), or just before formatting a number in base 10. Methods in this class are
usually <strong>not</strong>
- * recommended for intermediate calculations, since base 10 is not more "real" than base
2 for natural phenomenon.
+ * Functions working on {@code float} and {@code double} values while taking in account their
representation in base 10.
+ * Methods in this class may be helpful when used after parsing or before formatting a number
in base 10:
+ *
+ * <ul>
+ *   <li>Post-parsing methods {@link #floatToDouble(float)} and {@link #deltaForDoubleToDecimal(double)}:
+ *     <ul>
+ *       <li>for compensating error if the base 10 representation was <cite>definitive</cite>.</li>
+ *     </ul>
+ *   </li>
+ *   <li>Pre-formatting methods {@link #fractionDigitsForValue(double)} and
+ *       {@link #fractionDigitsForDelta(double, boolean)}:
+ *     <ul>
+ *       <li>for formatting the exact amount of significant digits for a given precision.</li>
+ *     </ul>
+ *   </li>
+ * </ul>
+ *
+ * Methods in this class are usually <strong>not</strong> recommended for intermediate
calculations,
+ * since base 10 is not more "real" than base 2 for natural phenomenon.
  *
  * @author  Martin Desruisseaux (Geomatys)
  * @since   0.4
@@ -169,10 +184,14 @@ public final class DecimalFunctions exte
      * {@preformat java
      *   BigDecimal base2  = new BigDecimal(value);     // Exact same value as stored in
IEEE 754 format.
      *   BigDecimal base10 = BigDecimal.valueOf(value); // Exact same value as shown by println(value).
-     *   return base10.subtract(base2).doubleValue();   // Magnitude always smaller than
Math.ulp(value).
+     *   return base10.subtract(base2).doubleValue();
      * }
      *
-     * {@section Use case}
+     * Computing {@code value + deltaForDoubleToDecimal(value)} has no effect since the absolute
value of the
+     * returned delta is always smaller than <code>{@linkplain Math#ulp(double) Math.ulp}(value)
/ 2</code>.
+     * To see an effect, a type with more precision than the {@code double} type is necessary.
+     *
+     * <blockquote><font size="-1"><b>Use case:</b>
      * Many international standards define values in base 10. For example the conversion
factor from inches
      * to centimetres is defined as exactly 2.54 cm/inch. This is by an internationally accepted
definition
      * since 1959, not an approximation. But the 2.54 value can not be represented exactly
in the IEEE 754
@@ -181,6 +200,7 @@ public final class DecimalFunctions exte
      * (e.g. in non-linear equations where errors can grow exponentially), this method can
be useful.
      * Other examples of values defined in base 10 are conversions from feet to metres and
      * map projection parameters defined by national mapping agencies.
+     * </font></blockquote>
      *
      * @param  value The value for which to get the delta compared to its base 10 representation.
      * @return The delta that would need to be added to the given {@code double} value for
getting

Modified: sis/branches/JDK7/core/sis-utility/src/test/java/org/apache/sis/math/DecimalFunctionsTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-utility/src/test/java/org/apache/sis/math/DecimalFunctionsTest.java?rev=1539609&r1=1539608&r2=1539609&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-utility/src/test/java/org/apache/sis/math/DecimalFunctionsTest.java
[UTF-8] (original)
+++ sis/branches/JDK7/core/sis-utility/src/test/java/org/apache/sis/math/DecimalFunctionsTest.java
[UTF-8] Thu Nov  7 12:21:48 2013
@@ -17,6 +17,7 @@
 package org.apache.sis.math;
 
 import java.util.Random;
+import java.math.BigDecimal;
 import org.junit.Test;
 import org.apache.sis.test.TestCase;
 import org.apache.sis.test.DependsOn;
@@ -41,14 +42,19 @@ import static org.apache.sis.math.Decima
 })
 public final strictfp class DecimalFunctionsTest extends TestCase {
     /**
+     * Tolerance threshold for strict comparisons of floating point values.
+     */
+    private static final double STRICT = 0;
+
+    /**
      * Verifies the values of {@link DecimalFunctions#EXPONENT_FOR_ZERO}.
      */
     @Test
     public void testConstants() {
-        assertEquals(0,  parseDouble("1E" +  EXPONENT_FOR_ZERO), 0);
+        assertEquals(0,  parseDouble("1E" +  EXPONENT_FOR_ZERO), STRICT);
         assertTrue  (0 < parseDouble("1E" + (EXPONENT_FOR_ZERO + 1)));
         assertTrue  (POSITIVE_INFINITY > parseDouble("1E" +  EXPONENT_FOR_MAX));
-        assertEquals(POSITIVE_INFINITY,  parseDouble("1E" + (EXPONENT_FOR_MAX + 1)), 0);
+        assertEquals(POSITIVE_INFINITY,  parseDouble("1E" + (EXPONENT_FOR_MAX + 1)), STRICT);
     }
 
     /**
@@ -59,7 +65,7 @@ public final strictfp class DecimalFunct
     @Test
     public void testPow10() {
         for (int i=EXPONENT_FOR_ZERO; i<=EXPONENT_FOR_MAX; i++) { // Range of allowed
exponents in base 10.
-            assertEquals(parseDouble("1E"+i), pow10(i), 0);
+            assertEquals(parseDouble("1E"+i), pow10(i), STRICT);
         }
     }
 
@@ -83,9 +89,58 @@ public final strictfp class DecimalFunct
             final float value = StrictMath.scalb(random.nextFloat(), random.nextInt(20) -
10);
             assertEquals(String.valueOf(value), String.valueOf(floatToDouble(value)));
         }
-        assertEquals(POSITIVE_INFINITY, floatToDouble(Float.POSITIVE_INFINITY), 0);
-        assertEquals(NEGATIVE_INFINITY, floatToDouble(Float.NEGATIVE_INFINITY), 0);
-        assertEquals(NaN,               floatToDouble(Float.NaN),               0);
+        assertEquals(POSITIVE_INFINITY, floatToDouble(Float.POSITIVE_INFINITY), STRICT);
+        assertEquals(NEGATIVE_INFINITY, floatToDouble(Float.NEGATIVE_INFINITY), STRICT);
+        assertEquals(NaN,               floatToDouble(Float.NaN),               STRICT);
+    }
+
+    /**
+     * Tests {@link DecimalFunctions#deltaForDoubleToDecimal(double)}.
+     */
+    @Test
+    @DependsOnMethod("testPow10")
+    public void testDeltaForDoubleToDecimal() {
+        assertEquals(0, deltaForDoubleToDecimal(0),                 STRICT);
+        assertEquals(0, deltaForDoubleToDecimal(1),                 STRICT);
+        assertEquals(0, deltaForDoubleToDecimal(NaN),               STRICT);
+        assertEquals(0, deltaForDoubleToDecimal(POSITIVE_INFINITY), STRICT);
+        assertEquals(0, deltaForDoubleToDecimal(NEGATIVE_INFINITY), STRICT);
+
+        assertEquals(-2.2204460492503132E-17, deltaForDoubleToDecimal(0.9),      STRICT);
+        assertEquals(-5.5511151231257827E-18, deltaForDoubleToDecimal(0.1),      STRICT);
+        assertEquals(-2.0816681711721684E-19, deltaForDoubleToDecimal(0.01),     STRICT);
+        assertEquals(-2.0816681711721686E-20, deltaForDoubleToDecimal(0.001),    STRICT);
+        assertEquals(-4.7921736023859296E-21, deltaForDoubleToDecimal(0.0001),   STRICT);
+        assertEquals(-8.1803053914031310E-22, deltaForDoubleToDecimal(0.00001),  STRICT);
+        assertEquals( 4.5251888174113741E-23, deltaForDoubleToDecimal(0.000001), STRICT);
+        assertEquals(-1.3471890270011499E-17, deltaForDoubleToDecimal(0.201168), STRICT);
// Link to metres
+        assertEquals(-1.5365486660812166E-17, deltaForDoubleToDecimal(0.3048),   STRICT);
// Feet to metres
+        assertEquals( 9.4146912488213275E-18, deltaForDoubleToDecimal(0.9144),   STRICT);
// Yard to metres
+        assertEquals( 1.8829382497642655E-17, deltaForDoubleToDecimal(1.8288),   STRICT);
// Fathom to metres
+        assertEquals(-3.5527136788005009E-17, deltaForDoubleToDecimal(2.54),     STRICT);
// Inch to centimetres
+        assertEquals(-1.3471890270011499E-15, deltaForDoubleToDecimal(20.1168),  STRICT);
// Chain to metres
+        /*
+         * Tests random value that do not use the full 'double' accuracy.
+         */
+        final Random random = TestUtilities.createRandomNumberGenerator();
+        for (int fractionDigits=0; fractionDigits<=9; fractionDigits++) {
+            for (int i=0; i<10; i++) {
+                final BigDecimal value = BigDecimal.valueOf(random.nextInt(1000000000)).movePointLeft(fractionDigits);
+                final double     ieee  = value.doubleValue(); // Inexact approximation of
value.
+                final BigDecimal delta = value.subtract(new BigDecimal(ieee));
+                assertEquals(delta.doubleValue(), deltaForDoubleToDecimal(ieee), STRICT);
+            }
+        }
+        /*
+         * Tests random values that do use the full 'double' accuracy.
+         */
+        for (int i=0; i<0; i++) { // TODO: disabled for now
+            final double     ieee  = random.nextDouble();
+            final String     text  = String.valueOf(ieee);
+            final BigDecimal value = new BigDecimal(text);
+            final BigDecimal delta = value.subtract(new BigDecimal(ieee));
+            assertEquals(text, delta.doubleValue(), deltaForDoubleToDecimal(ieee), STRICT);
+        }
     }
 
     /**

Modified: sis/branches/JDK7/core/sis-utility/src/test/java/org/apache/sis/math/MathFunctionsTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-utility/src/test/java/org/apache/sis/math/MathFunctionsTest.java?rev=1539609&r1=1539608&r2=1539609&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-utility/src/test/java/org/apache/sis/math/MathFunctionsTest.java
[UTF-8] (original)
+++ sis/branches/JDK7/core/sis-utility/src/test/java/org/apache/sis/math/MathFunctionsTest.java
[UTF-8] Thu Nov  7 12:21:48 2013
@@ -45,6 +45,11 @@ import org.apache.sis.internal.jdk8.JDK8
 })
 public final strictfp class MathFunctionsTest extends TestCase {
     /**
+     * Tolerance threshold for strict comparisons of floating point values.
+     */
+    private static final double STRICT = 0;
+
+    /**
      * Small number for floating point comparisons.
      */
     private static final double EPS = 1E-12;
@@ -64,8 +69,8 @@ public final strictfp class MathFunction
      */
     @Test
     public void testConstants() {
-        assertEquals(StrictMath.sqrt (2), SQRT_2,  0);
-        assertEquals(StrictMath.log10(2), LOG10_2, 0);
+        assertEquals(StrictMath.sqrt (2), SQRT_2,  STRICT);
+        assertEquals(StrictMath.log10(2), LOG10_2, STRICT);
     }
 
     /**
@@ -74,10 +79,10 @@ public final strictfp class MathFunction
     @Test
     @DependsOnMethod({"testIsPositiveZero", "testIsNegativeZero"})
     public void testTruncate() {
-        assertEquals(+4.0, truncate(+4.9), 0);
-        assertEquals(-4.0, truncate(-4.9), 0);
-        assertEquals(+0.0, truncate(+0.1), 0);
-        assertEquals(-0.0, truncate(-0.1), 0);
+        assertEquals(+4.0, truncate(+4.9), STRICT);
+        assertEquals(-4.0, truncate(-4.9), STRICT);
+        assertEquals(+0.0, truncate(+0.1), STRICT);
+        assertEquals(-0.0, truncate(-0.1), STRICT);
         assertTrue("Positive zero", isPositiveZero(truncate(+0.5)));
         assertTrue("Negative zero", isNegativeZero(truncate(-0.5)));
         assertTrue("Positive zero", isPositiveZero(truncate(+0.0)));
@@ -144,7 +149,7 @@ public final strictfp class MathFunction
          */
         for (int i = MIN_EXPONENT - SIGNIFICAND_SIZE; i <= MAX_EXPONENT; i++) {
             assertEquals(StrictMath.floor(StrictMath.log10(StrictMath.scalb(1.0, i))),
-                         StrictMath.floor(LOG10_2 * i /* i = getExponent(value) */), 0);
+                         StrictMath.floor(LOG10_2 * i /* i = getExponent(value) */), STRICT);
         }
     }
 
@@ -189,10 +194,10 @@ public final strictfp class MathFunction
      */
     @Test
     public void testXorSign() {
-        assertEquals( 10, xorSign( 10,  0.5), 0);
-        assertEquals(-10, xorSign(-10,  0.5), 0);
-        assertEquals( 10, xorSign(-10, -0.5), 0);
-        assertEquals(-10, xorSign( 10, -0.5), 0);
+        assertEquals( 10, xorSign( 10,  0.5), STRICT);
+        assertEquals(-10, xorSign(-10,  0.5), STRICT);
+        assertEquals( 10, xorSign(-10, -0.5), STRICT);
+        assertEquals(-10, xorSign( 10, -0.5), STRICT);
     }
 
     /**

Modified: sis/branches/JDK7/core/sis-utility/src/test/java/org/apache/sis/math/StatisticsTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-utility/src/test/java/org/apache/sis/math/StatisticsTest.java?rev=1539609&r1=1539608&r2=1539609&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-utility/src/test/java/org/apache/sis/math/StatisticsTest.java
[UTF-8] (original)
+++ sis/branches/JDK7/core/sis-utility/src/test/java/org/apache/sis/math/StatisticsTest.java
[UTF-8] Thu Nov  7 12:21:48 2013
@@ -52,6 +52,11 @@ public final strictfp class StatisticsTe
     private static final double EPS = 1E-10;
 
     /**
+     * Tolerance threshold for strict comparisons of floating point values.
+     */
+    private static final double STRICT = 0;
+
+    /**
      * Tests the initial state of newly constructed instance.
      */
     @Test
@@ -217,8 +222,8 @@ public final strictfp class StatisticsTe
             }
             assertEquals(global.count(),    byBlock.count());
             assertEquals(global.countNaN(), byBlock.countNaN());
-            assertEquals(global.minimum(),  byBlock.minimum(), 0.0);
-            assertEquals(global.maximum(),  byBlock.maximum(), 0.0);
+            assertEquals(global.minimum(),  byBlock.minimum(), STRICT);
+            assertEquals(global.maximum(),  byBlock.maximum(), STRICT);
             assertEquals(global.mean(),     byBlock.mean(),    1E-15);
             assertEquals(global.rms(),      byBlock.rms(),     1E-15);
         }
@@ -240,8 +245,8 @@ public final strictfp class StatisticsTe
         assertNotSame(statistics, after);
         assertEquals( 3,                 after.count());
         assertEquals( 1,                 after.countNaN());
-        assertEquals(10.0,               after.minimum(),                0.0);
-        assertEquals(40.0,               after.maximum(),                0.0);
+        assertEquals(10.0,               after.minimum(),             STRICT);
+        assertEquals(40.0,               after.maximum(),             STRICT);
         assertEquals(23.333333333333333, after.mean(),                   EPS);
         assertEquals(26.457513110645905, after.rms(),                    EPS);
         assertEquals(12.472191289246473, after.standardDeviation(true),  EPS);



Mime
View raw message