You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by lu...@apache.org on 2009/03/29 18:51:48 UTC

svn commit: r759725 - in /commons/proper/math/trunk/src: java/org/apache/commons/math/fraction/Fraction.java site/xdoc/changes.xml test/org/apache/commons/math/fraction/FractionTest.java

Author: luc
Date: Sun Mar 29 16:51:48 2009
New Revision: 759725

URL: http://svn.apache.org/viewvc?rev=759725&view=rev
Log:
Fixed a comparison error when two different fractions evaluate to the
same double due to limited precision.
Jira: MATH-252

Modified:
    commons/proper/math/trunk/src/java/org/apache/commons/math/fraction/Fraction.java
    commons/proper/math/trunk/src/site/xdoc/changes.xml
    commons/proper/math/trunk/src/test/org/apache/commons/math/fraction/FractionTest.java

Modified: commons/proper/math/trunk/src/java/org/apache/commons/math/fraction/Fraction.java
URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/java/org/apache/commons/math/fraction/Fraction.java?rev=759725&r1=759724&r2=759725&view=diff
==============================================================================
--- commons/proper/math/trunk/src/java/org/apache/commons/math/fraction/Fraction.java (original)
+++ commons/proper/math/trunk/src/java/org/apache/commons/math/fraction/Fraction.java Sun Mar 29 16:51:48 2009
@@ -256,20 +256,9 @@
      *         than <tt>object</tt>, 0 if they are equal.
      */
     public int compareTo(Fraction object) {
-        int ret = 0;
-        
-        if (this != object) { 
-            double first = doubleValue();
-            double second = object.doubleValue();
-            
-            if (first < second) {
-                ret = -1;
-            } else if (first > second) {
-                ret = 1;
-            }
-        }
-        
-        return ret;
+        long nOd = ((long) numerator) * object.denominator;
+        long dOn = ((long) denominator) * object.numerator;
+        return (nOd < dOn) ? -1 : ((nOd > dOn) ? +1 : 0);
     }
     
     /**

Modified: commons/proper/math/trunk/src/site/xdoc/changes.xml
URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/site/xdoc/changes.xml?rev=759725&r1=759724&r2=759725&view=diff
==============================================================================
--- commons/proper/math/trunk/src/site/xdoc/changes.xml (original)
+++ commons/proper/math/trunk/src/site/xdoc/changes.xml Sun Mar 29 16:51:48 2009
@@ -39,6 +39,10 @@
   </properties>
   <body>
     <release version="2.0" date="TBD" description="TBD">
+      <action dev="luc" type="fix" issue="MATH-252">
+        Fixed a comparison error when two different fractions evaluate to the
+        same double due to limited precision.
+      </action>
       <action dev="luc" type="add" issue="MATH-251" due-to="Benjamin Croizet">
         Added a BigFraction class that does not overflow when big numerators or
         denominators are used.

Modified: commons/proper/math/trunk/src/test/org/apache/commons/math/fraction/FractionTest.java
URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/test/org/apache/commons/math/fraction/FractionTest.java?rev=759725&r1=759724&r2=759725&view=diff
==============================================================================
--- commons/proper/math/trunk/src/test/org/apache/commons/math/fraction/FractionTest.java (original)
+++ commons/proper/math/trunk/src/test/org/apache/commons/math/fraction/FractionTest.java Sun Mar 29 16:51:48 2009
@@ -169,6 +169,15 @@
         assertEquals(0, first.compareTo(third));
         assertEquals(1, first.compareTo(second));
         assertEquals(-1, second.compareTo(first));
+
+        // these two values are different approximations of PI
+        // the first  one is approximately PI - 3.07e-18
+        // the second one is approximately PI + 1.936e-17
+        Fraction pi1 = new Fraction(1068966896, 340262731);
+        Fraction pi2 = new Fraction( 411557987, 131002976);
+        assertEquals(-1, pi1.compareTo(pi2));
+        assertEquals( 1, pi2.compareTo(pi1));
+        assertEquals(0.0, pi1.doubleValue() - pi2.doubleValue(), 1.0e-20);
     }
     
     public void testDoubleValue() {