OSDN Git Service

Fix java.util.Formatter formatting of -0.0.
authorElliott Hughes <enh@google.com>
Wed, 9 Dec 2009 08:44:31 +0000 (00:44 -0800)
committerElliott Hughes <enh@google.com>
Wed, 9 Dec 2009 08:44:31 +0000 (00:44 -0800)
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.

libcore/icu/src/main/java/com/ibm/icu4jni/text/DecimalFormat.java
libcore/luni/src/main/java/java/util/Formatter.java
libcore/text/src/main/java/java/text/NumberFormat.java

index 104336e..81c7578 100644 (file)
@@ -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;
     }
 
index 071995c..0b92a87 100644 (file)
@@ -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': {
index 87f17c1..23b0e27 100644 (file)
@@ -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();
     }