diff --git a/src/main/java/org/apache/xmlbeans/impl/util/XsTypeConverter.java b/src/main/java/org/apache/xmlbeans/impl/util/XsTypeConverter.java index afcd131f3..405a4b252 100644 --- a/src/main/java/org/apache/xmlbeans/impl/util/XsTypeConverter.java +++ b/src/main/java/org/apache/xmlbeans/impl/util/XsTypeConverter.java @@ -279,7 +279,8 @@ public static String printDecimal(BigDecimal value) { // The following code comes from Apache Harmony String intStr = value.unscaledValue().toString(); int scale = value.scale(); - if (scale == 0 || (MathUtil.toLong(value) == 0 && scale < 0)) { + // the second branch only needs a zero check, as in the original Harmony code + if (scale == 0 || (value.signum() == 0 && scale < 0)) { return intStr; } diff --git a/src/test/java/misc/checkin/XsTypeConverterTest.java b/src/test/java/misc/checkin/XsTypeConverterTest.java index 1865e7f81..acb23a16e 100644 --- a/src/test/java/misc/checkin/XsTypeConverterTest.java +++ b/src/test/java/misc/checkin/XsTypeConverterTest.java @@ -22,6 +22,8 @@ import org.apache.xmlbeans.impl.values.XmlValueOutOfRangeException; import org.junit.jupiter.api.Test; +import java.math.BigDecimal; + import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertThrows; @@ -309,4 +311,27 @@ public java.util.Iterator getPrefixes(String uri) { assertEquals("", empty.getLocalPart()); assertEquals(1, errors.size()); } + + @Test + void printDecimalHandlesValuesWiderThanLong() { + assertEquals("123456789012345678901234567890.5", + XsTypeConverter.printDecimal(new BigDecimal("123456789012345678901234567890.5"))); + assertEquals("-123456789012345678901234567890.5", + XsTypeConverter.printDecimal(new BigDecimal("-123456789012345678901234567890.5"))); + } + + @Test + void printDecimalHandlesNegativeScaleWiderThanLong() { + // stripTrailingZeros() and BigDecimal.valueOf(unscaled, negativeScale) both + // produce negative-scale values, which reach printDecimal via setBigDecimalValue. + assertEquals("100000000000000000000", XsTypeConverter.printDecimal(new BigDecimal("1E+20"))); + assertEquals("-100000000000000000000", XsTypeConverter.printDecimal(new BigDecimal("-1E+20"))); + assertEquals("100", XsTypeConverter.printDecimal(new BigDecimal("1E+2"))); + } + + @Test + void printDecimalHandlesZeroWithScale() { + assertEquals("0", XsTypeConverter.printDecimal(new BigDecimal("0E+5"))); + assertEquals("0.00000", XsTypeConverter.printDecimal(new BigDecimal("0E-5"))); + } }