fix BigDecimal.compareTo and precision for leading zeros
http://code.google.com/p/google-web-toolkit/issues/detail?id=7834
Fixes issue 7834
Based on a patch by jat@jaet.org
Change-Id: I9874897f54a9eb6ce15f5b7b6295613800a25b72
Review-Link: https://gwt-review.googlesource.com/#/c/1660/
git-svn-id: https://google-web-toolkit.googlecode.com/svn/trunk@11494 8db76d5a-ed1c-0410-87a9-c151d255dfc7
diff --git a/user/super/com/google/gwt/emul/java/math/BigDecimal.java b/user/super/com/google/gwt/emul/java/math/BigDecimal.java
index 7cc988b..ffbdfb7 100644
--- a/user/super/com/google/gwt/emul/java/math/BigDecimal.java
+++ b/user/super/com/google/gwt/emul/java/math/BigDecimal.java
@@ -2615,18 +2615,10 @@
throw new NumberFormatException("For input string: \"" + val + "\"");
}
}
- int counter = 0;
- boolean wasNonZero = false;
// Accumulating all digits until a possible decimal point
- for (; (offset < last) && (val.charAt(offset) != '.')
- && (val.charAt(offset) != 'e') && (val.charAt(offset) != 'E'); offset++) {
- if (!wasNonZero) {
- if (val.charAt(offset) == '0') {
- counter++;
- } else {
- wasNonZero = true;
- }
- }
+ while ((offset < last) && (val.charAt(offset) != '.')
+ && (val.charAt(offset) != 'e') && (val.charAt(offset) != 'E')) {
+ offset++;
}
unscaledBuffer.append(val, begin, offset);
// A decimal point was found
@@ -2634,15 +2626,9 @@
offset++;
// Accumulating all digits until a possible exponent
begin = offset;
- for (; (offset < last) && (val.charAt(offset) != 'e')
- && (val.charAt(offset) != 'E'); offset++) {
- if (!wasNonZero) {
- if (val.charAt(offset) == '0') {
- counter++;
- } else {
- wasNonZero = true;
- }
- }
+ while ((offset < last) && (val.charAt(offset) != 'e')
+ && (val.charAt(offset) != 'E')) {
+ offset++;
}
scale = offset - begin;
unscaledBuffer.append(val, begin, offset);
@@ -2681,7 +2667,7 @@
} else {
setUnscaledValue(new BigInteger(unscaled));
}
- precision = unscaledBuffer.length() - counter;
+ precision = unscaledBuffer.length();
// Don't count leading zeros in the precision
for (int i = 0; i < unscaledBuffer.length(); ++i) {
char ch = unscaledBuffer.charAt(i);
@@ -2690,6 +2676,10 @@
}
--precision;
}
+ // The precision of a zero value is 1
+ if (precision == 0) {
+ precision = 1;
+ }
}
/**
diff --git a/user/test/com/google/gwt/emultest/java/math/BigDecimalCompareTest.java b/user/test/com/google/gwt/emultest/java/math/BigDecimalCompareTest.java
index 794309e..474ce3a 100644
--- a/user/test/com/google/gwt/emultest/java/math/BigDecimalCompareTest.java
+++ b/user/test/com/google/gwt/emultest/java/math/BigDecimalCompareTest.java
@@ -248,6 +248,23 @@
}
/**
+ * Test identical fraction values with different scales.
+ * http://code.google.com/p/google-web-toolkit/issues/detail?id=7834
+ */
+ public void testFractionScale() {
+ BigDecimal a = new BigDecimal("0.02");
+ BigDecimal b = new BigDecimal("0.02000");
+ assertEquals(0, a.compareTo(b));
+
+ BigDecimal a1 = new BigDecimal("0.029900000000000003");
+ BigDecimal a2 = new BigDecimal("0.0001");
+ a = a1.add(a2);
+ // a is 0.030000000000000003 (0.029900000000000003 + 0.0001)
+ b = new BigDecimal("0.03990");
+ assertEquals(-1, a.compareTo(b));
+ }
+
+ /**
* hashCode() for equal BigDecimals.
*/
public void testHashCodeEqual() {
diff --git a/user/test/com/google/gwt/emultest/java/math/BigDecimalConstructorsTest.java b/user/test/com/google/gwt/emultest/java/math/BigDecimalConstructorsTest.java
index aa5765c..15bdee8 100644
--- a/user/test/com/google/gwt/emultest/java/math/BigDecimalConstructorsTest.java
+++ b/user/test/com/google/gwt/emultest/java/math/BigDecimalConstructorsTest.java
@@ -687,11 +687,19 @@
}
/**
- * Test second failing example in gwt-java-math issue 4.
+ * Test second failing example in gwt-java-math issue 4 and variations
+ * to validate that precision is calculated correctly when leading zeros
+ * and minus signs are present.
*/
public void testConstrStringWithLeadingZeros() {
- BigDecimal value = new BigDecimal("-000.1");
- assertEquals("bad precision", 1, value.precision());
+ assertEquals("bad precision", 1, new BigDecimal("-000.1").precision());
+ assertEquals("bad precision", 4, new BigDecimal("001234").precision());
+ assertEquals("bad precision", 4, new BigDecimal("-5555").precision());
+ assertEquals("bad precision", 1, new BigDecimal("0").precision());
+ assertEquals("bad precision", 1, new BigDecimal("-0").precision());
+ assertEquals("bad precision", 4, new BigDecimal("001234e3").precision());
+ assertEquals("bad precision", 5, new BigDecimal("00056789e+17").precision());
+ assertEquals("bad precision", 6, new BigDecimal("0900000e-42").precision());
}
/**