ICU-11653 Override roundingMode API from the NumberFormat superclass so that it doesn...
authorGeorge Rhoten <grhoten@users.noreply.github.com>
Tue, 25 Aug 2015 19:33:18 +0000 (19:33 +0000)
committerGeorge Rhoten <grhoten@users.noreply.github.com>
Tue, 25 Aug 2015 19:33:18 +0000 (19:33 +0000)
X-SVN-Rev: 37812

icu4j/main/classes/core/src/com/ibm/icu/text/RuleBasedNumberFormat.java
icu4j/main/tests/core/src/com/ibm/icu/dev/test/format/RbnfTest.java

index cab35dfbbd3785f4538ab8526ec0ae99c475d9e1..2e7820c897cb27f7f788e108530ca58c3bacc558 100644 (file)
@@ -21,6 +21,7 @@ import com.ibm.icu.impl.ICUDebug;
 import com.ibm.icu.impl.ICUResourceBundle;
 import com.ibm.icu.impl.PatternProps;
 import com.ibm.icu.lang.UCharacter;
+import com.ibm.icu.math.BigDecimal;
 import com.ibm.icu.util.ULocale;
 import com.ibm.icu.util.ULocale.Category;
 import com.ibm.icu.util.UResourceBundle;
@@ -593,6 +594,12 @@ public class RuleBasedNumberFormat extends NumberFormat {
      */
     private ULocale locale = null;
 
+    /**
+     * The formatter's rounding mode.
+     * @serial
+     */
+    private int roundingMode = BigDecimal.ROUND_UNNECESSARY;
+
     /**
      * Collator to be used in lenient parsing.  This variable is lazy-evaluated:
      * the collator is actually created the first time the client does a parse
@@ -968,6 +975,7 @@ public class RuleBasedNumberFormat extends NumberFormat {
         // have an implementation-independent streaming format
         out.writeUTF(this.toString());
         out.writeObject(this.locale);
+        out.writeInt(this.roundingMode);
     }
 
     /**
@@ -986,6 +994,10 @@ public class RuleBasedNumberFormat extends NumberFormat {
         } catch (Exception e) {
             loc = ULocale.getDefault(Category.FORMAT);
         }
+        try {
+            roundingMode = in.readInt();
+        } catch (Exception ignored) {
+        }
 
         // build a brand-new RuleBasedNumberFormat from the description,
         // then steal its substructure.  This object's substructure and
@@ -999,6 +1011,8 @@ public class RuleBasedNumberFormat extends NumberFormat {
         decimalFormatSymbols = temp.decimalFormatSymbols;
         decimalFormat = temp.decimalFormat;
         locale = temp.locale;
+        defaultInfinityRule = temp.defaultInfinityRule;
+        defaultNaNRule = temp.defaultNaNRule;
     }
 
 
@@ -1491,6 +1505,41 @@ public class RuleBasedNumberFormat extends NumberFormat {
         }
     }
 
+    /**
+     * Returns the rounding mode.
+     *
+     * @return A rounding mode, between <code>BigDecimal.ROUND_UP</code> and
+     * <code>BigDecimal.ROUND_UNNECESSARY</code>.
+     * @see #setRoundingMode
+     * @see java.math.BigDecimal
+     * @draft ICU 56
+     */
+    @Override
+    public int getRoundingMode() {
+        return roundingMode;
+    }
+
+    /**
+     * Sets the rounding mode. This has no effect unless the rounding increment is greater
+     * than zero.
+     *
+     * @param roundingMode A rounding mode, between <code>BigDecimal.ROUND_UP</code> and
+     * <code>BigDecimal.ROUND_UNNECESSARY</code>.
+     * @exception IllegalArgumentException if <code>roundingMode</code> is unrecognized.
+     * @see #getRoundingMode
+     * @see java.math.BigDecimal
+     * @draft ICU 56
+     */
+    @Override
+    public void setRoundingMode(int roundingMode) {
+        if (roundingMode < BigDecimal.ROUND_UP || roundingMode > BigDecimal.ROUND_UNNECESSARY) {
+            throw new IllegalArgumentException("Invalid rounding mode: " + roundingMode);
+        }
+
+        this.roundingMode = roundingMode;
+    }
+
+
     //-----------------------------------------------------------------------
     // package-internal API
     //-----------------------------------------------------------------------
@@ -1879,6 +1928,9 @@ public class RuleBasedNumberFormat extends NumberFormat {
         // position of 0 and the number being formatted) to the rule set
         // for formatting
         StringBuffer result = new StringBuffer();
+        if (getRoundingMode() != BigDecimal.ROUND_UNNECESSARY) {
+            number = new BigDecimal(number).setScale(getMaximumFractionDigits(), roundingMode).doubleValue();
+        }
         ruleSet.format(number, result, 0, 0);
         postProcess(result, ruleSet);
         return result.toString();
index 8159ffee05e87e343926d1e242b693c3b8ffca43..dfd7b177db1075291f5f47ce82fddd71c5b42ea6 100644 (file)
@@ -12,6 +12,7 @@ import java.util.Locale;
 import java.util.Random;
 
 import com.ibm.icu.dev.test.TestFmwk;
+import com.ibm.icu.math.BigDecimal;
 import com.ibm.icu.text.DecimalFormat;
 import com.ibm.icu.text.DecimalFormatSymbols;
 import com.ibm.icu.text.DisplayContext;
@@ -1404,7 +1405,7 @@ public class RbnfTest extends TestFmwk {
         String[] ruleNames = rbnf.getRuleSetNames();
         try{
             // Test with "null" rules
-            rbnf.format(0.0,null);
+            rbnf.format(0.0, null);
             errln("This was suppose to return an exception for a null format");
         } catch(Exception e){}
         for(int i=0; i<ruleNames.length; i++){
@@ -1555,4 +1556,38 @@ public class RbnfTest extends TestFmwk {
         doTest(enFormatter, enTestCommaData, true);
     }
 
+    public void TestRounding() {
+        RuleBasedNumberFormat enFormatter = new RuleBasedNumberFormat(ULocale.ENGLISH, RuleBasedNumberFormat.SPELLOUT);
+        String[][] enTestPointData = {
+                {"0", "zero"},
+                {"0.4", "zero point four"},
+                {"0.49", "zero point four nine"},
+                {"0.5", "zero point five"},
+                {"0.51", "zero point five one"},
+                {"0.99", "zero point nine nine"},
+                {"1", "one"},
+                {"1.01", "one point zero one"},
+                {"1.49", "one point four nine"},
+                {"1.5", "one point five"},
+                {"1.51", "one point five one"},
+        };
+        doTest(enFormatter, enTestPointData, false);
+
+        enFormatter.setMaximumFractionDigits(0);
+        enFormatter.setRoundingMode(BigDecimal.ROUND_HALF_EVEN);
+        String[][] enTestCommaData = {
+                {"0", "zero"},
+                {"0.4", "zero"},
+                {"0.49", "zero"},
+                {"0.5", "zero"},
+                {"0.51", "one"},
+                {"0.99", "one"},
+                {"1", "one"},
+                {"1.01", "one"},
+                {"1.49", "one"},
+                {"1.5", "two"},
+                {"1.51", "two"},
+        };
+        doTest(enFormatter, enTestCommaData, false);
+    }
 }