summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorElliott Hughes <enh@google.com>2009-12-09 00:44:31 -0800
committerElliott Hughes <enh@google.com>2009-12-09 00:44:31 -0800
commita1e5d8a2c1594f7a6ed8aca6e82b106ec8ce79d6 (patch)
tree3d10059faaea4384f64f60d35e2037da48edf963
parent58a69a9059cbb7efd518526cf1077603eb06241a (diff)
downloadlibcore-a1e5d8a2c1594f7a6ed8aca6e82b106ec8ce79d6.zip
libcore-a1e5d8a2c1594f7a6ed8aca6e82b106ec8ce79d6.tar.gz
libcore-a1e5d8a2c1594f7a6ed8aca6e82b106ec8ce79d6.tar.bz2
Fix java.util.Formatter formatting of -0.0.
The active ingredient here is the two changes to stop comparing longValue with doubleValue and formatting the long if the two compare equal. This causes us to lose the sign of 0 (because there's no long -0, but -0.0d == 0). Instead, we explicitly test for boxed Double and Float arguments (because the number of integral types is larger, they get the "else" clause). The other changes are just minor cosmetic changes made as I followed the code. Bug found by jtreg, so no new test.
-rw-r--r--icu/src/main/java/com/ibm/icu4jni/text/DecimalFormat.java53
-rw-r--r--luni/src/main/java/java/util/Formatter.java32
-rw-r--r--text/src/main/java/java/text/NumberFormat.java9
3 files changed, 34 insertions, 60 deletions
diff --git a/icu/src/main/java/com/ibm/icu4jni/text/DecimalFormat.java b/icu/src/main/java/com/ibm/icu4jni/text/DecimalFormat.java
index 104336e..81c7578 100644
--- a/icu/src/main/java/com/ibm/icu4jni/text/DecimalFormat.java
+++ b/icu/src/main/java/com/ibm/icu4jni/text/DecimalFormat.java
@@ -135,24 +135,20 @@ public class DecimalFormat extends NumberFormat {
@Override
public StringBuffer format(Object value, StringBuffer buffer, FieldPosition field) {
-
- if(!(value instanceof Number)) {
+ if (!(value instanceof Number)) {
throw new IllegalArgumentException();
}
- if(buffer == null || field == null) {
+ if (buffer == null || field == null) {
throw new NullPointerException();
}
-
String fieldType = getFieldType(field.getFieldAttribute());
-
Number number = (Number) value;
-
- if(number instanceof BigInteger) {
+ if (number instanceof BigInteger) {
BigInteger valBigInteger = (BigInteger) number;
- String result = NativeDecimalFormat.format(this.addr,
- valBigInteger.toString(10), field, fieldType, null, 0);
+ String result = NativeDecimalFormat.format(this.addr, valBigInteger.toString(10),
+ field, fieldType, null, 0);
return buffer.append(result);
- } else if(number instanceof BigDecimal) {
+ } else if (number instanceof BigDecimal) {
BigDecimal valBigDecimal = (BigDecimal) number;
if (getMultiplier() != 1) {
valBigDecimal = applyMultiplier(valBigDecimal);
@@ -161,54 +157,39 @@ public class DecimalFormat extends NumberFormat {
val.append(valBigDecimal.unscaledValue().toString(10));
int scale = valBigDecimal.scale();
scale = makeScalePositive(scale, val);
- String result = NativeDecimalFormat.format(this.addr,
- val.toString(), field, fieldType, null, scale);
+ String result = NativeDecimalFormat.format(this.addr, val.toString(),
+ field, fieldType, null, scale);
return buffer.append(result);
- } else {
+ } else if (number instanceof Double || number instanceof Float) {
double dv = number.doubleValue();
+ String result = NativeDecimalFormat.format(this.addr, dv, field, fieldType, null);
+ return buffer.append(result);
+ } else {
long lv = number.longValue();
- if (dv == lv) {
- String result = NativeDecimalFormat.format(this.addr, lv, field,
- fieldType, null);
- return buffer.append(result);
- }
- String result = NativeDecimalFormat.format(this.addr, dv, field,
- fieldType, null);
+ String result = NativeDecimalFormat.format(this.addr, lv, field, fieldType, null);
return buffer.append(result);
}
}
@Override
public StringBuffer format(long value, StringBuffer buffer, FieldPosition field) {
-
- if(buffer == null || field == null) {
+ if (buffer == null || field == null) {
throw new NullPointerException();
}
-
String fieldType = getFieldType(field.getFieldAttribute());
-
- String result = NativeDecimalFormat.format(this.addr, value, field,
- fieldType, null);
-
+ String result = NativeDecimalFormat.format(this.addr, value, field, fieldType, null);
buffer.append(result.toCharArray(), 0, result.length());
-
return buffer;
}
@Override
public StringBuffer format(double value, StringBuffer buffer, FieldPosition field) {
-
- if(buffer == null || field == null) {
+ if (buffer == null || field == null) {
throw new NullPointerException();
}
-
String fieldType = getFieldType(field.getFieldAttribute());
-
- String result = NativeDecimalFormat.format(this.addr, value, field,
- fieldType, null);
-
+ String result = NativeDecimalFormat.format(this.addr, value, field, fieldType, null);
buffer.append(result.toCharArray(), 0, result.length());
-
return buffer;
}
diff --git a/luni/src/main/java/java/util/Formatter.java b/luni/src/main/java/java/util/Formatter.java
index 071995c..0b92a87 100644
--- a/luni/src/main/java/java/util/Formatter.java
+++ b/luni/src/main/java/java/util/Formatter.java
@@ -1777,9 +1777,7 @@ public final class Formatter implements Closeable, Flushable {
if ('d' == currentConversionType) {
NumberFormat numberFormat = getNumberFormat();
- boolean readableName = formatToken
- .isFlagSet(FormatToken.FLAG_COMMA);
- numberFormat.setGroupingUsed(readableName);
+ numberFormat.setGroupingUsed(formatToken.isFlagSet(FormatToken.FLAG_COMMA));
result.append(numberFormat.format(bigInt));
} else if ('o' == currentConversionType) {
// convert BigInteger to a string presentation using radix 8
@@ -1884,16 +1882,15 @@ public final class Formatter implements Closeable, Flushable {
return specialNumberResult;
}
- if ('a' != Character.toLowerCase(currentConversionType)) {
- formatToken
- .setPrecision(formatToken.isPrecisionSet() ? formatToken
- .getPrecision()
- : FormatToken.DEFAULT_PRECISION);
+ if (Character.toLowerCase(currentConversionType) != 'a' &&
+ !formatToken.isPrecisionSet()) {
+ formatToken.setPrecision(FormatToken.DEFAULT_PRECISION);
}
+
// output result
FloatUtil floatUtil = new FloatUtil(result, formatToken,
(DecimalFormat) getNumberFormat(), arg);
- floatUtil.transform(formatToken, result);
+ floatUtil.transform();
formatToken.setPrecision(FormatToken.UNSET);
@@ -1979,15 +1976,15 @@ public final class Formatter implements Closeable, Flushable {
}
private static class FloatUtil {
- private StringBuilder result;
+ private final StringBuilder result;
- private DecimalFormat decimalFormat;
+ private final DecimalFormat decimalFormat;
- private FormatToken formatToken;
+ private final FormatToken formatToken;
- private Object argument;
+ private final Object argument;
- private char minusSign;
+ private final char minusSign;
FloatUtil(StringBuilder result, FormatToken formatToken,
DecimalFormat decimalFormat, Object argument) {
@@ -1995,13 +1992,10 @@ public final class Formatter implements Closeable, Flushable {
this.formatToken = formatToken;
this.decimalFormat = decimalFormat;
this.argument = argument;
- this.minusSign = decimalFormat.getDecimalFormatSymbols()
- .getMinusSign();
+ this.minusSign = decimalFormat.getDecimalFormatSymbols().getMinusSign();
}
- void transform(FormatToken aFormatToken, StringBuilder aResult) {
- this.result = aResult;
- this.formatToken = aFormatToken;
+ void transform() {
switch (formatToken.getConversionType()) {
case 'e':
case 'E': {
diff --git a/text/src/main/java/java/text/NumberFormat.java b/text/src/main/java/java/text/NumberFormat.java
index 87f17c1..23b0e27 100644
--- a/text/src/main/java/java/text/NumberFormat.java
+++ b/text/src/main/java/java/text/NumberFormat.java
@@ -301,13 +301,12 @@ public abstract class NumberFormat extends Format {
@Override
public StringBuffer format(Object object, StringBuffer buffer,
FieldPosition field) {
- if (object instanceof Number) {
+ if (object instanceof Double || object instanceof Float) {
double dv = ((Number) object).doubleValue();
- long lv = ((Number) object).longValue();
- if (dv == lv) {
- return format(lv, buffer, field);
- }
return format(dv, buffer, field);
+ } else if (object instanceof Number) {
+ long lv = ((Number) object).longValue();
+ return format(lv, buffer, field);
}
throw new IllegalArgumentException();
}