diff --git a/src/main/java/org/apache/commons/math/dfp/Dfp.java b/src/main/java/org/apache/commons/math/dfp/Dfp.java index 04e66132d..54aabc411 100644 --- a/src/main/java/org/apache/commons/math/dfp/Dfp.java +++ b/src/main/java/org/apache/commons/math/dfp/Dfp.java @@ -163,7 +163,7 @@ public class Dfp implements FieldElement { /** Mantissa. */ protected int[] mant; - /** Sign bit: & for positive, -1 for negative. */ + /** Sign bit: 1 for positive, -1 for negative. */ protected byte sign; /** Exponent. */ @@ -269,6 +269,10 @@ public class Dfp implements FieldElement { if (exponent == -1023) { // Zero or sub-normal if (x == 0) { + // make sure 0 has the right sign + if ((bits & 0x8000000000000000L) != 0) { + sign = -1; + } return; } @@ -2315,7 +2319,10 @@ public class Dfp implements FieldElement { Dfp y = this; boolean negate = false; - if (lessThan(getZero())) { + int cmp0 = compare(this, getZero()); + if (cmp0 == 0) { + return sign < 0 ? -0.0 : +0.0; + } else if (cmp0 < 0) { y = negate(); negate = true; } diff --git a/src/site/xdoc/changes.xml b/src/site/xdoc/changes.xml index 8f3901486..dd5c56276 100644 --- a/src/site/xdoc/changes.xml +++ b/src/site/xdoc/changes.xml @@ -52,6 +52,9 @@ The type attribute can be add,update,fix,remove. If the output is not quite correct, check for invisible trailing spaces! --> + + Fixed conversion problems to/from 0 in Decimal Floating Point (Dfp) class. + Fixed initialization of multistep ODE integrators. Relying on the interpolation model of the starter integrator inside only one step was wrong. The model may have a too diff --git a/src/test/java/org/apache/commons/math/dfp/DfpTest.java b/src/test/java/org/apache/commons/math/dfp/DfpTest.java index db5c05ce5..d8426c3ae 100644 --- a/src/test/java/org/apache/commons/math/dfp/DfpTest.java +++ b/src/test/java/org/apache/commons/math/dfp/DfpTest.java @@ -17,6 +17,8 @@ package org.apache.commons.math.dfp; +import org.apache.commons.math.util.FastMath; +import org.apache.commons.math.util.MathUtils; import org.junit.After; import org.junit.Assert; import org.junit.Before; @@ -1504,4 +1506,13 @@ public class DfpTest { DfpField.FLAG_INVALID, "Sqrt #9"); } + @Test + public void testIssue567() { + DfpField field = new DfpField(100); + Assert.assertEquals(0.0, field.getZero().toDouble(), MathUtils.SAFE_MIN); + Assert.assertEquals(0.0, field.newDfp(0.0).toDouble(), MathUtils.SAFE_MIN); + Assert.assertEquals(-1, FastMath.copySign(1, field.newDfp(-0.0).toDouble()), MathUtils.EPSILON); + Assert.assertEquals(+1, FastMath.copySign(1, field.newDfp(+0.0).toDouble()), MathUtils.EPSILON); + } + }