Fixed a comparison error when two different fractions evaluate to the

same double due to limited precision.
Jira: MATH-252


git-svn-id: https://svn.apache.org/repos/asf/commons/proper/math/trunk@759725 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Luc Maisonobe 2009-03-29 16:51:48 +00:00
parent 312b1ca42e
commit 99b46033f5
3 changed files with 16 additions and 14 deletions

View File

@ -256,20 +256,9 @@ public class Fraction extends Number implements Comparable<Fraction> {
* than <tt>object</tt>, 0 if they are equal. * than <tt>object</tt>, 0 if they are equal.
*/ */
public int compareTo(Fraction object) { public int compareTo(Fraction object) {
int ret = 0; long nOd = ((long) numerator) * object.denominator;
long dOn = ((long) denominator) * object.numerator;
if (this != object) { return (nOd < dOn) ? -1 : ((nOd > dOn) ? +1 : 0);
double first = doubleValue();
double second = object.doubleValue();
if (first < second) {
ret = -1;
} else if (first > second) {
ret = 1;
}
}
return ret;
} }
/** /**

View File

@ -39,6 +39,10 @@ The <action> type attribute can be add,update,fix,remove.
</properties> </properties>
<body> <body>
<release version="2.0" date="TBD" description="TBD"> <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"> <action dev="luc" type="add" issue="MATH-251" due-to="Benjamin Croizet">
Added a BigFraction class that does not overflow when big numerators or Added a BigFraction class that does not overflow when big numerators or
denominators are used. denominators are used.

View File

@ -169,6 +169,15 @@ public class FractionTest extends TestCase {
assertEquals(0, first.compareTo(third)); assertEquals(0, first.compareTo(third));
assertEquals(1, first.compareTo(second)); assertEquals(1, first.compareTo(second));
assertEquals(-1, second.compareTo(first)); 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() { public void testDoubleValue() {