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 2008/02/01 13:02:20 UTC
svn commit: r617482 - in /commons/proper/math/trunk:
src/java/org/apache/commons/math/ src/java/org/apache/commons/math/fraction/
src/test/org/apache/commons/math/fraction/ xdocs/
Author: luc
Date: Fri Feb 1 04:02:12 2008
New Revision: 617482
URL: http://svn.apache.org/viewvc?rev=617482&view=rev
Log:
added checks for integer overflows during double to Fraction conversion
JIRA: MATH-182
Modified:
commons/proper/math/trunk/src/java/org/apache/commons/math/MessagesResources_fr.java
commons/proper/math/trunk/src/java/org/apache/commons/math/fraction/Fraction.java
commons/proper/math/trunk/src/java/org/apache/commons/math/fraction/FractionConversionException.java
commons/proper/math/trunk/src/test/org/apache/commons/math/fraction/FractionTest.java
commons/proper/math/trunk/xdocs/changes.xml
Modified: commons/proper/math/trunk/src/java/org/apache/commons/math/MessagesResources_fr.java
URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/java/org/apache/commons/math/MessagesResources_fr.java?rev=617482&r1=617481&r2=617482&view=diff
==============================================================================
--- commons/proper/math/trunk/src/java/org/apache/commons/math/MessagesResources_fr.java (original)
+++ commons/proper/math/trunk/src/java/org/apache/commons/math/MessagesResources_fr.java Fri Feb 1 04:02:12 2008
@@ -71,6 +71,8 @@
// org.apache.commons.math.fraction.FractionConversionException
{ "Unable to convert {0} to fraction after {1} iterations",
"Impossible de convertir {0} en fraction apr\u00e8s {1} it\u00e9rations" },
+ { "Overflow trying to convert {0} to fraction ({1}/{2})",
+ "D\u00e9passement de capacit\u00e9 lors de la conversion de {0} en fraction ({1}/{2})" },
// org.apache.commons.math.analysis.UnivariateRealSolverUtils
{ "Number of iterations={0}, maximum iterations={1}, initial={2}, lower bound={3}, upper bound={4}," +
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=617482&r1=617481&r2=617482&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 Fri Feb 1 04:02:12 2008
@@ -34,7 +34,7 @@
public static final Fraction ZERO = new Fraction(0, 1);
/** Serializable version identifier */
- private static final long serialVersionUID = 5463066929751300926L;
+ private static final long serialVersionUID = -8958519416450949235L;
/** The denominator. */
private int denominator;
@@ -128,33 +128,40 @@
private Fraction(double value, double epsilon, int maxDenominator, int maxIterations)
throws FractionConversionException
{
+ long overflow = Integer.MAX_VALUE;
double r0 = value;
- int a0 = (int)Math.floor(r0);
+ long a0 = (long)Math.floor(r0);
+ if (a0 > overflow) {
+ throw new FractionConversionException(value, a0, 1l);
+ }
// check for (almost) integer arguments, which should not go
// to iterations.
if (Math.abs(a0 - value) < epsilon) {
- this.numerator = a0;
+ this.numerator = (int) a0;
this.denominator = 1;
return;
}
-
- int p0 = 1;
- int q0 = 0;
- int p1 = a0;
- int q1 = 1;
- int p2 = 0;
- int q2 = 1;
+ long p0 = 1;
+ long q0 = 0;
+ long p1 = a0;
+ long q1 = 1;
+
+ long p2 = 0;
+ long q2 = 1;
int n = 0;
boolean stop = false;
do {
++n;
double r1 = 1.0 / (r0 - a0);
- int a1 = (int)Math.floor(r1);
+ long a1 = (long)Math.floor(r1);
p2 = (a1 * p1) + p0;
q2 = (a1 * q1) + q0;
+ if ((p2 > overflow) || (q2 > overflow)) {
+ throw new FractionConversionException(value, p2, q2);
+ }
double convergent = (double)p2 / (double)q2;
if (n < maxIterations && Math.abs(convergent - value) > epsilon && q2 < maxDenominator) {
@@ -174,11 +181,11 @@
}
if (q2 < maxDenominator) {
- this.numerator = p2;
- this.denominator = q2;
+ this.numerator = (int) p2;
+ this.denominator = (int) q2;
} else {
- this.numerator = p1;
- this.denominator = q1;
+ this.numerator = (int) p1;
+ this.denominator = (int) q1;
}
}
Modified: commons/proper/math/trunk/src/java/org/apache/commons/math/fraction/FractionConversionException.java
URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/java/org/apache/commons/math/fraction/FractionConversionException.java?rev=617482&r1=617481&r2=617482&view=diff
==============================================================================
--- commons/proper/math/trunk/src/java/org/apache/commons/math/fraction/FractionConversionException.java (original)
+++ commons/proper/math/trunk/src/java/org/apache/commons/math/fraction/FractionConversionException.java Fri Feb 1 04:02:12 2008
@@ -17,7 +17,7 @@
package org.apache.commons.math.fraction;
-import org.apache.commons.math.MaxIterationsExceededException;
+import org.apache.commons.math.ConvergenceException;
/**
* Error thrown when a double value cannot be converted to a fraction
@@ -25,10 +25,10 @@
*
* @version $Revision$ $Date$
*/
-public class FractionConversionException extends MaxIterationsExceededException {
+public class FractionConversionException extends ConvergenceException {
/** Serializable version identifier. */
- private static final long serialVersionUID = 4588659344016668813L;
+ private static final long serialVersionUID = -4661812640132576263L;
/**
* Constructs an exception with specified formatted detail message.
@@ -37,9 +37,20 @@
* @param maxIterations maximal number of iterations allowed
*/
public FractionConversionException(double value, int maxIterations) {
- super(maxIterations,
- "Unable to convert {0} to fraction after {1} iterations",
+ super("Unable to convert {0} to fraction after {1} iterations",
new Object[] { new Double(value), new Integer(maxIterations) });
+ }
+
+ /**
+ * Constructs an exception with specified formatted detail message.
+ * Message formatting is delegated to {@link java.text.MessageFormat}.
+ * @param value double value to convert
+ * @param p current numerator
+ * @param q current denominator
+ */
+ public FractionConversionException(double value, long p, long q) {
+ super("Overflow trying to convert {0} to fraction ({1}/{2})",
+ new Object[] { new Double(value), new Long(p), new Long(q) });
}
}
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=617482&r1=617481&r2=617482&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 Fri Feb 1 04:02:12 2008
@@ -133,6 +133,22 @@
assertFraction(769, 1250, new Fraction(0.6152, 9999));
}
+ public void testIntegerOverflow() {
+ checkIntegerOverflow(0.75000000001455192);
+ checkIntegerOverflow(1.0e10);
+ }
+
+ private void checkIntegerOverflow(double a) {
+ try {
+ new Fraction(a, 1.0e-12, 1000);
+ fail("an exception should have been thrown");
+ } catch (ConvergenceException ce) {
+ // expected behavior
+ } catch (Exception e) {
+ fail("wrong exception caught");
+ }
+ }
+
public void testEpsilonLimitConstructor() throws ConvergenceException {
assertFraction(2, 5, new Fraction(0.4, 1.0e-5, 100));
Modified: commons/proper/math/trunk/xdocs/changes.xml
URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/xdocs/changes.xml?rev=617482&r1=617481&r2=617482&view=diff
==============================================================================
--- commons/proper/math/trunk/xdocs/changes.xml (original)
+++ commons/proper/math/trunk/xdocs/changes.xml Fri Feb 1 04:02:12 2008
@@ -136,6 +136,9 @@
<action dev="luc" type="update" issue="MATH-181" due-to="Niall Pemberton">
Add Fraction constructor using max denominator value.
</action>
+ <action dev="luc" type="fix" issue="MATH-18x">
+ Add integer overflow checks in Fraction constructor using double parameter.
+ </action>
</release>
<release version="1.1" date="2005-12-17"
description="This is a maintenance release containing bug fixes and enhancements.