sis-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From desruisse...@apache.org
Subject svn commit: r1535053 - in /sis/branches/JDK7/core/sis-utility/src: main/java/org/apache/sis/measure/AngleFormat.java test/java/org/apache/sis/measure/AngleFormatTest.java test/java/org/apache/sis/measure/AngleTest.java
Date Wed, 23 Oct 2013 15:13:50 GMT
Author: desruisseaux
Date: Wed Oct 23 15:13:50 2013
New Revision: 1535053

URL: http://svn.apache.org/r1535053
Log:
Fixed a rounding error when formatting angles.

Modified:
    sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/measure/AngleFormat.java
    sis/branches/JDK7/core/sis-utility/src/test/java/org/apache/sis/measure/AngleFormatTest.java
    sis/branches/JDK7/core/sis-utility/src/test/java/org/apache/sis/measure/AngleTest.java

Modified: sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/measure/AngleFormat.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/measure/AngleFormat.java?rev=1535053&r1=1535052&r2=1535053&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/measure/AngleFormat.java
[UTF-8] (original)
+++ sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/measure/AngleFormat.java
[UTF-8] Wed Oct 23 15:13:50 2013
@@ -39,7 +39,7 @@ import static java.lang.Double.isInfinit
 import static org.apache.sis.math.MathFunctions.pow10;
 import static org.apache.sis.math.MathFunctions.truncate;
 import static org.apache.sis.math.MathFunctions.isNegative;
-import static org.apache.sis.math.MathFunctions.fractionDigitsForValue;
+import static org.apache.sis.math.MathFunctions.fractionDigitsForDelta;
 
 // Related to JDK7
 import java.util.Objects;
@@ -895,7 +895,7 @@ public class AngleFormat extends Format 
      *
      * @return The {@code toAppendTo} buffer, returned for method calls chaining.
      */
-    public StringBuffer format(double angle, StringBuffer toAppendTo, final FieldPosition
pos) {
+    public StringBuffer format(final double angle, StringBuffer toAppendTo, final FieldPosition
pos) {
         final int offset = toAppendTo.length();
         final int fieldPos = getField(pos);
         if (isNaN(angle) || isInfinite(angle)) {
@@ -913,9 +913,18 @@ public class AngleFormat extends Format 
         double degrees = angle;
         double minutes = NaN;
         double seconds = NaN;
+        int maximumFractionDigits = fractionFieldWidth;
         if (minutesFieldWidth != 0 && !isNaN(angle)) {
             minutes = abs(degrees - (degrees = truncate(degrees))) * 60;
-            final double p = pow10(fractionFieldWidth);
+            /*
+             * Limit the maximal number of fraction digits to the amount of significant digits
for a 'double' value.
+             * The intend is to avoid non-significant garbage that are pure artifacts from
the conversion from base
+             * 2 to base 10.
+             */
+            final int n = fractionDigitsForDelta(Math.ulp(angle) * (secondsFieldWidth ==
0 ? 60 : 3600), false);
+            final double p = pow10(Math.max(1, Math.min(maximumFractionDigits, n)));
+            maximumFractionDigits = Math.max(minimumFractionDigits,
+                                    Math.min(maximumFractionDigits, n - 1));
             if (secondsFieldWidth != 0) {
                 seconds = (minutes - (minutes = truncate(minutes))) * 60;
                 seconds = rint(seconds * p) / p; // Correction for rounding errors.
@@ -946,22 +955,7 @@ public class AngleFormat extends Format 
             }
         }
         /*
-         * At this point the 'degrees', 'minutes' and 'seconds' variables contain the final
values
-         * to format. But before to perform the numbers formating,  if the pattern uses a
variable
-         * number of fraction digits, then limit the maximal number to the amount of significant
-         * fraction digits for a 'double' value. The intend is to avoid non-significant garbage
-         * that are pure artifacts from the conversion from base 2 to base 10.
-         */
-        int maximumFractionDigits = fractionFieldWidth;
-        if (maximumFractionDigits != minimumFractionDigits) {
-            if      (secondsFieldWidth != 0) angle *= 3600;
-            else if (minutesFieldWidth != 0) angle *=   60;
-            final int n = fractionDigitsForValue(angle) - 1;
-            if (n < maximumFractionDigits) {
-                maximumFractionDigits = Math.max(minimumFractionDigits, n);
-            }
-        }
-        /*
+         * At this point the 'degrees', 'minutes' and 'seconds' variables contain the final
values to format.
          * The following loop will format fields from DEGREES_FIELD to SECONDS_FIELD inclusive.
          * The NumberFormat will be reconfigured at each iteration.
          */
@@ -1041,12 +1035,12 @@ public class AngleFormat extends Format 
                 }
                 final Number userObject;
                 if (hasMore) {
-                    userObject = (int) Math.round(value);
+                    userObject = Integer.valueOf((int) Math.round(value));
                 } else {
                     // Use Float instead of Double because we don't want to give a false
impression of accuracy
                     // (when formatting the seconds field, at least the 10 last bits of the
'double' value are
                     // non-significant).
-                    userObject = (float) value;
+                    userObject = Float.valueOf((float) value);
                 }
                 it.addFieldLimit(Field.forCode(field), userObject, startPosition);
             } else {

Modified: sis/branches/JDK7/core/sis-utility/src/test/java/org/apache/sis/measure/AngleFormatTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-utility/src/test/java/org/apache/sis/measure/AngleFormatTest.java?rev=1535053&r1=1535052&r2=1535053&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-utility/src/test/java/org/apache/sis/measure/AngleFormatTest.java
[UTF-8] (original)
+++ sis/branches/JDK7/core/sis-utility/src/test/java/org/apache/sis/measure/AngleFormatTest.java
[UTF-8] Wed Oct 23 15:13:50 2013
@@ -136,6 +136,7 @@ public final strictfp class AngleFormatT
         assertEquals( "12°30.0", formatAndParse(f, new Angle( 12.50)));
         assertEquals("-10°15.0", formatAndParse(f, new Angle(-10.25)));
         assertEquals("-00°00.6", formatAndParse(f, new Angle( -0.01)));
+        assertEquals( "89°01.0", formatAndParse(f, new Angle( 89.01666666666667)));
     }
 
     /**
@@ -151,6 +152,7 @@ public final strictfp class AngleFormatT
         assertEquals( "12°30′56.250″", formatAndParse(f, new Angle( 12.515625)));
         assertEquals("-12°30′56.250″", formatAndParse(f, new Angle(-12.515625)));
         assertEquals("-00°00′36.000″", formatAndParse(f, new Angle( -0.01)));
+        assertEquals( "89°01′00.000″", formatAndParse(f, new Angle( 89.01666666666667)));
     }
 
     /**

Modified: sis/branches/JDK7/core/sis-utility/src/test/java/org/apache/sis/measure/AngleTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-utility/src/test/java/org/apache/sis/measure/AngleTest.java?rev=1535053&r1=1535052&r2=1535053&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-utility/src/test/java/org/apache/sis/measure/AngleTest.java
[UTF-8] (original)
+++ sis/branches/JDK7/core/sis-utility/src/test/java/org/apache/sis/measure/AngleTest.java
[UTF-8] Wed Oct 23 15:13:50 2013
@@ -44,6 +44,7 @@ public final strictfp class AngleTest ex
         assertEquals("45°30′N",       new Latitude (45.5).toString());
         assertEquals("45°30′E",       new Longitude(45.5).toString());
         assertEquals("45°30′56.25″E", new Longitude(45.515625).toString());
+        assertEquals("89°01′N",       new Latitude (89.01666666666667).toString());
 
         // Angle out of expected range.
         assertEquals( "720.0°E", new Longitude( 720).toString());



Mime
View raw message