diff --git a/src/changes/changes.xml b/src/changes/changes.xml
index 067865423..f3dd93dab 100644
--- a/src/changes/changes.xml
+++ b/src/changes/changes.xml
@@ -51,6 +51,10 @@ If the output is not quite correct, check for invisible trailing spaces!
+
+ Fix "Precision#round(float, int, int)" when using rounding mode "BigDecimal.ROUND_UP"
+ and the discarded fraction is zero.
+
Use "FastMath" instead of "Math" within Commons Math.
diff --git a/src/main/java/org/apache/commons/math3/util/Precision.java b/src/main/java/org/apache/commons/math3/util/Precision.java
index ef3b57f39..f0b0c4ff7 100644
--- a/src/main/java/org/apache/commons/math3/util/Precision.java
+++ b/src/main/java/org/apache/commons/math3/util/Precision.java
@@ -491,8 +491,7 @@ public class Precision {
unscaled = FastMath.floor(unscaled);
} else {
// The following equality test is intentional and needed for rounding purposes
- if (FastMath.floor(unscaled) / 2.0 == FastMath.floor(Math
- .floor(unscaled) / 2.0)) { // even
+ if (FastMath.floor(unscaled) / 2.0 == FastMath.floor(FastMath.floor(unscaled) / 2.0)) { // even
unscaled = FastMath.floor(unscaled);
} else { // odd
unscaled = FastMath.ceil(unscaled);
@@ -516,7 +515,10 @@ public class Precision {
}
break;
case BigDecimal.ROUND_UP :
- unscaled = FastMath.ceil(FastMath.nextAfter(unscaled, Double.POSITIVE_INFINITY));
+ // do not round if the discarded fraction is equal to zero
+ if (unscaled != FastMath.floor(unscaled)) {
+ unscaled = FastMath.ceil(FastMath.nextAfter(unscaled, Double.POSITIVE_INFINITY));
+ }
break;
default :
throw new MathIllegalArgumentException(LocalizedFormats.INVALID_ROUNDING_METHOD,
diff --git a/src/test/java/org/apache/commons/math3/util/PrecisionTest.java b/src/test/java/org/apache/commons/math3/util/PrecisionTest.java
index ca833fcb5..f73d11752 100644
--- a/src/test/java/org/apache/commons/math3/util/PrecisionTest.java
+++ b/src/test/java/org/apache/commons/math3/util/PrecisionTest.java
@@ -490,6 +490,13 @@ public class PrecisionTest {
Assert.assertEquals(0.0f, Precision.round(0.0f, 2), 0.0f);
Assert.assertEquals(Float.POSITIVE_INFINITY, Precision.round(Float.POSITIVE_INFINITY, 2), 0.0f);
Assert.assertEquals(Float.NEGATIVE_INFINITY, Precision.round(Float.NEGATIVE_INFINITY, 2), 0.0f);
+
+ // MATH-1070
+ Assert.assertEquals(0.0f, Precision.round(0f, 2, BigDecimal.ROUND_UP), 0.0f);
+ Assert.assertEquals(0.05f, Precision.round(0.05f, 2, BigDecimal.ROUND_UP), 0.0f);
+ Assert.assertEquals(0.06f, Precision.round(0.051f, 2, BigDecimal.ROUND_UP), 0.0f);
+ Assert.assertEquals(0.06f, Precision.round(0.0505f, 2, BigDecimal.ROUND_UP), 0.0f);
+ Assert.assertEquals(0.06f, Precision.round(0.059f, 2, BigDecimal.ROUND_UP), 0.0f);
}