]> git.saurik.com Git - apple/icu.git/blobdiff - icuSources/test/intltest/numberformat2test.cpp
ICU-57131.0.1.tar.gz
[apple/icu.git] / icuSources / test / intltest / numberformat2test.cpp
diff --git a/icuSources/test/intltest/numberformat2test.cpp b/icuSources/test/intltest/numberformat2test.cpp
new file mode 100644 (file)
index 0000000..6beb35b
--- /dev/null
@@ -0,0 +1,3088 @@
+/*
+*******************************************************************************
+* Copyright (C) 2015, International Business Machines Corporation and         *
+* others. All Rights Reserved.                                                *
+*******************************************************************************
+*
+* File NUMBERFORMAT2TEST.CPP
+*
+*******************************************************************************
+*/
+#include "unicode/utypes.h"
+
+#include "intltest.h"
+
+#if !UCONFIG_NO_FORMATTING
+
+#include "unicode/localpointer.h"
+#include "unicode/plurrule.h"
+
+#include "affixpatternparser.h"
+#include "charstr.h"
+#include "datadrivennumberformattestsuite.h"
+#include "decimalformatpattern.h"
+#include "digitaffixesandpadding.h"
+#include "digitformatter.h"
+#include "digitgrouping.h"
+#include "digitinterval.h"
+#include "digitlst.h"
+#include "fphdlimp.h"
+#include "plurrule_impl.h"
+#include "precision.h"
+#include "significantdigitinterval.h"
+#include "smallintformatter.h"
+#include "uassert.h"
+#include "valueformatter.h"
+#include "visibledigits.h"
+
+struct NumberFormat2Test_Attributes {
+    int32_t id;
+    int32_t spos;
+    int32_t epos;
+};
+
+class NumberFormat2Test_FieldPositionHandler : public FieldPositionHandler {
+public:
+NumberFormat2Test_Attributes attributes[100];
+int32_t count;
+UBool bRecording;
+
+
+
+NumberFormat2Test_FieldPositionHandler() : count(0), bRecording(TRUE) { attributes[0].spos = -1; }
+NumberFormat2Test_FieldPositionHandler(UBool recording) : count(0), bRecording(recording) { attributes[0].spos = -1; }
+virtual ~NumberFormat2Test_FieldPositionHandler();
+virtual void addAttribute(int32_t id, int32_t start, int32_t limit);
+virtual void shiftLast(int32_t delta);
+virtual UBool isRecording(void) const;
+};
+NumberFormat2Test_FieldPositionHandler::~NumberFormat2Test_FieldPositionHandler() {
+}
+
+void NumberFormat2Test_FieldPositionHandler::addAttribute(
+        int32_t id, int32_t start, int32_t limit) {
+    if (count == UPRV_LENGTHOF(attributes) - 1) {
+        return;
+    }
+    attributes[count].id = id;
+    attributes[count].spos = start;
+    attributes[count].epos = limit;
+    ++count;
+    attributes[count].spos = -1;
+}
+
+void NumberFormat2Test_FieldPositionHandler::shiftLast(int32_t /* delta */) {
+}
+
+UBool NumberFormat2Test_FieldPositionHandler::isRecording() const {
+    return bRecording;
+}
+
+
+class NumberFormat2Test : public IntlTest {
+public:
+    void runIndexedTest(int32_t index, UBool exec, const char *&name, char *par=0);
+private:
+    void TestQuantize();
+    void TestConvertScientificNotation();
+    void TestLowerUpperExponent();
+    void TestRounding();
+    void TestRoundingIncrement();
+    void TestDigitInterval();
+    void TestGroupingUsed();
+    void TestBenchmark();
+    void TestBenchmark2();
+    void TestSmallIntFormatter();
+    void TestPositiveIntDigitFormatter();
+    void TestDigitListInterval();
+    void TestLargeIntValue();
+    void TestIntInitVisibleDigits();
+    void TestIntInitVisibleDigitsToDigitList();
+    void TestDoubleInitVisibleDigits();
+    void TestDoubleInitVisibleDigitsToDigitList();
+    void TestDigitListInitVisibleDigits();
+    void TestSpecialInitVisibleDigits();
+    void TestVisibleDigitsWithExponent();
+    void TestDigitAffixesAndPadding();
+    void TestPluralsAndRounding();
+    void TestPluralsAndRoundingScientific();
+    void TestValueFormatterIsFastFormattable();
+    void TestCurrencyAffixInfo();
+    void TestAffixPattern();
+    void TestAffixPatternAppend();
+    void TestAffixPatternAppendAjoiningLiterals();
+    void TestAffixPatternDoubleQuote();
+    void TestAffixPatternParser();
+    void TestPluralAffix();
+    void TestDigitAffix();
+    void TestDigitFormatterDefaultCtor();
+    void TestDigitFormatterMonetary();
+    void TestDigitFormatter();
+    void TestSciFormatterDefaultCtor();
+    void TestSciFormatter();
+    void TestToPatternScientific11648();
+    void verifyInterval(const DigitInterval &, int32_t minInclusive, int32_t maxExclusive);
+    void verifyAffix(
+            const UnicodeString &expected,
+            const DigitAffix &affix,
+            const NumberFormat2Test_Attributes *expectedAttributes);
+    void verifyAffixesAndPadding(
+            const UnicodeString &expected,
+            const DigitAffixesAndPadding &aaf,
+            DigitList &digits,
+            const ValueFormatter &vf,
+            const PluralRules *optPluralRules,
+            const NumberFormat2Test_Attributes *expectedAttributes);
+    void verifyAffixesAndPaddingInt32(
+            const UnicodeString &expected,
+            const DigitAffixesAndPadding &aaf,
+            int32_t value,
+            const ValueFormatter &vf,
+            const PluralRules *optPluralRules,
+            const NumberFormat2Test_Attributes *expectedAttributes);
+    void verifyDigitList(
+        const UnicodeString &expected,
+        const DigitList &digits);
+    void verifyVisibleDigits(
+        const UnicodeString &expected,
+        UBool bNegative,
+        const VisibleDigits &digits);
+    void verifyVisibleDigitsWithExponent(
+        const UnicodeString &expected,
+        UBool bNegative,
+        const VisibleDigitsWithExponent &digits);
+    void verifyDigitFormatter(
+            const UnicodeString &expected,
+            const DigitFormatter &formatter,
+            const VisibleDigits &digits,
+            const DigitGrouping &grouping,
+            const DigitFormatterOptions &options,
+            const NumberFormat2Test_Attributes *expectedAttributes);
+    void verifySciFormatter(
+            const UnicodeString &expected,
+            const DigitFormatter &formatter,
+            const VisibleDigitsWithExponent &digits,
+            const SciFormatterOptions &options,
+            const NumberFormat2Test_Attributes *expectedAttributes);
+    void verifySmallIntFormatter(
+            const UnicodeString &expected,
+            int32_t positiveValue,
+            int32_t minDigits,
+            int32_t maxDigits);
+    void verifyPositiveIntDigitFormatter(
+            const UnicodeString &expected,
+            const DigitFormatter &formatter,
+            int32_t value,
+            int32_t minDigits,
+            int32_t maxDigits,
+            const NumberFormat2Test_Attributes *expectedAttributes);
+    void verifyAttributes(
+            const NumberFormat2Test_Attributes *expected,
+            const NumberFormat2Test_Attributes *actual);
+    void verifyIntValue(
+            int64_t expected, const VisibleDigits &digits);
+    void verifySource(
+            double expected, const VisibleDigits &digits);
+};
+
+void NumberFormat2Test::runIndexedTest(
+        int32_t index, UBool exec, const char *&name, char *) {
+    if (exec) {
+        logln("TestSuite ScientificNumberFormatterTest: ");
+    }
+    TESTCASE_AUTO_BEGIN;
+    TESTCASE_AUTO(TestQuantize);
+    TESTCASE_AUTO(TestConvertScientificNotation);
+    TESTCASE_AUTO(TestLowerUpperExponent);
+    TESTCASE_AUTO(TestRounding);
+    TESTCASE_AUTO(TestRoundingIncrement);
+    TESTCASE_AUTO(TestDigitInterval);
+    TESTCASE_AUTO(TestGroupingUsed);
+    TESTCASE_AUTO(TestDigitListInterval);
+    TESTCASE_AUTO(TestDigitFormatterDefaultCtor);
+    TESTCASE_AUTO(TestDigitFormatterMonetary);
+    TESTCASE_AUTO(TestDigitFormatter);
+    TESTCASE_AUTO(TestSciFormatterDefaultCtor);
+    TESTCASE_AUTO(TestSciFormatter);
+    TESTCASE_AUTO(TestBenchmark);
+    TESTCASE_AUTO(TestBenchmark2);
+    TESTCASE_AUTO(TestSmallIntFormatter);
+    TESTCASE_AUTO(TestPositiveIntDigitFormatter);
+    TESTCASE_AUTO(TestCurrencyAffixInfo);
+    TESTCASE_AUTO(TestAffixPattern);
+    TESTCASE_AUTO(TestAffixPatternAppend);
+    TESTCASE_AUTO(TestAffixPatternAppendAjoiningLiterals);
+    TESTCASE_AUTO(TestAffixPatternDoubleQuote);
+    TESTCASE_AUTO(TestAffixPatternParser);
+    TESTCASE_AUTO(TestPluralAffix);
+    TESTCASE_AUTO(TestDigitAffix);
+    TESTCASE_AUTO(TestValueFormatterIsFastFormattable);
+    TESTCASE_AUTO(TestLargeIntValue);
+    TESTCASE_AUTO(TestIntInitVisibleDigits);
+    TESTCASE_AUTO(TestIntInitVisibleDigitsToDigitList);
+    TESTCASE_AUTO(TestDoubleInitVisibleDigits);
+    TESTCASE_AUTO(TestDoubleInitVisibleDigitsToDigitList);
+    TESTCASE_AUTO(TestDigitListInitVisibleDigits);
+    TESTCASE_AUTO(TestSpecialInitVisibleDigits);
+    TESTCASE_AUTO(TestVisibleDigitsWithExponent);
+    TESTCASE_AUTO(TestDigitAffixesAndPadding);
+    TESTCASE_AUTO(TestPluralsAndRounding);
+    TESTCASE_AUTO(TestPluralsAndRoundingScientific);
+    TESTCASE_AUTO(TestToPatternScientific11648);
+    TESTCASE_AUTO_END;
+}
+
+void NumberFormat2Test::TestDigitInterval() {
+    DigitInterval all;
+    DigitInterval threeInts;
+    DigitInterval fourFrac;
+    threeInts.setIntDigitCount(3);
+    fourFrac.setFracDigitCount(4);
+    verifyInterval(all, INT32_MIN, INT32_MAX);
+    verifyInterval(threeInts, INT32_MIN, 3);
+    verifyInterval(fourFrac, -4, INT32_MAX);
+    {
+        DigitInterval result(threeInts);
+        result.shrinkToFitWithin(fourFrac);
+        verifyInterval(result, -4, 3);
+        assertEquals("", 7, result.length());
+    }
+    {
+        DigitInterval result(threeInts);
+        result.expandToContain(fourFrac);
+        verifyInterval(result, INT32_MIN, INT32_MAX);
+    }
+    {
+        DigitInterval result(threeInts);
+        result.setIntDigitCount(0);
+        verifyInterval(result, INT32_MIN, 0);
+        result.setIntDigitCount(-1);
+        verifyInterval(result, INT32_MIN, INT32_MAX);
+    }
+    {
+        DigitInterval result(fourFrac);
+        result.setFracDigitCount(0);
+        verifyInterval(result, 0, INT32_MAX);
+        result.setFracDigitCount(-1);
+        verifyInterval(result, INT32_MIN, INT32_MAX);
+    }
+    {
+        DigitInterval result;
+        result.setIntDigitCount(3);
+        result.setFracDigitCount(1);
+        result.expandToContainDigit(0);
+        result.expandToContainDigit(-1);
+        result.expandToContainDigit(2);
+        verifyInterval(result, -1, 3);
+        result.expandToContainDigit(3);
+        verifyInterval(result, -1, 4);
+        result.expandToContainDigit(-2);
+        verifyInterval(result, -2, 4);
+        result.expandToContainDigit(15);
+        result.expandToContainDigit(-15);
+        verifyInterval(result, -15, 16);
+    }
+    {
+        DigitInterval result;
+        result.setIntDigitCount(3);
+        result.setFracDigitCount(1);
+        assertTrue("", result.contains(2));
+        assertTrue("", result.contains(-1));
+        assertFalse("", result.contains(3));
+        assertFalse("", result.contains(-2));
+    }
+}
+
+void NumberFormat2Test::verifyInterval(
+        const DigitInterval &interval,
+        int32_t minInclusive, int32_t maxExclusive) {
+    assertEquals("", minInclusive, interval.getLeastSignificantInclusive());
+    assertEquals("", maxExclusive, interval.getMostSignificantExclusive());
+    assertEquals("", maxExclusive, interval.getIntDigitCount());
+}
+
+void NumberFormat2Test::TestGroupingUsed() {
+    {
+        DigitGrouping grouping;
+        assertFalse("", grouping.isGroupingUsed());
+    }
+    {
+        DigitGrouping grouping;
+        grouping.fGrouping = 2;
+        assertTrue("", grouping.isGroupingUsed());
+    }
+}
+
+void NumberFormat2Test::TestDigitListInterval() {
+    DigitInterval result;
+    DigitList digitList;
+    {
+        digitList.set(12345);
+        verifyInterval(digitList.getSmallestInterval(result), 0, 5);
+    }
+    {
+        digitList.set(1000.00);
+        verifyInterval(digitList.getSmallestInterval(result), 0, 4);
+    }
+    {
+        digitList.set(43.125);
+        verifyInterval(digitList.getSmallestInterval(result), -3, 2);
+    }
+    {
+        digitList.set(.0078125);
+        verifyInterval(digitList.getSmallestInterval(result), -7, 0);
+    }
+    {
+        digitList.set(1000.00);
+        digitList.getSmallestInterval(result);
+        result.expandToContainDigit(3);
+        verifyInterval(result, 0, 4);
+    }
+    {
+        digitList.set(1000.00);
+        digitList.getSmallestInterval(result);
+        result.expandToContainDigit(4);
+        verifyInterval(result, 0, 5);
+    }
+    {
+        digitList.set(1000.00);
+        digitList.getSmallestInterval(result);
+        result.expandToContainDigit(0);
+        verifyInterval(result, 0, 4);
+    }
+    {
+        digitList.set(1000.00);
+        digitList.getSmallestInterval(result);
+        result.expandToContainDigit(-1);
+        verifyInterval(result, -1, 4);
+    }
+    {
+        digitList.set(43.125);
+        digitList.getSmallestInterval(result);
+        result.expandToContainDigit(1);
+        verifyInterval(result, -3, 2);
+    }
+    {
+        digitList.set(43.125);
+        digitList.getSmallestInterval(result);
+        result.expandToContainDigit(2);
+        verifyInterval(result, -3, 3);
+    }
+    {
+        digitList.set(43.125);
+        digitList.getSmallestInterval(result);
+        result.expandToContainDigit(-3);
+        verifyInterval(result, -3, 2);
+    }
+    {
+        digitList.set(43.125);
+        digitList.getSmallestInterval(result);
+        result.expandToContainDigit(-4);
+        verifyInterval(result, -4, 2);
+    }
+}
+
+void NumberFormat2Test::TestQuantize() {
+    DigitList quantity;
+    quantity.set(0.00168);
+    quantity.roundAtExponent(-5);
+    DigitList digits;
+    UErrorCode status = U_ZERO_ERROR;
+    {
+        digits.set(1);
+        digits.quantize(quantity, status);
+        verifyDigitList(".9996", digits);
+    }
+    {
+        // round half even up
+        digits.set(1.00044);
+        digits.roundAtExponent(-5);
+        digits.quantize(quantity, status);
+        verifyDigitList("1.00128", digits);
+    }
+    {
+        // round half down
+        digits.set(0.99876);
+        digits.roundAtExponent(-5);
+        digits.quantize(quantity, status);
+        verifyDigitList(".99792", digits);
+    }
+    assertSuccess("", status);
+}
+
+void NumberFormat2Test::TestConvertScientificNotation() {
+    DigitList digits;
+    {
+        digits.set(186283);
+        assertEquals("", 5, digits.toScientific(1, 1));
+        verifyDigitList(
+                "1.86283",
+                digits);
+    }
+    {
+        digits.set(186283);
+        assertEquals("", 0, digits.toScientific(6, 1));
+        verifyDigitList(
+                "186283",
+                digits);
+    }
+    {
+        digits.set(186283);
+        assertEquals("", -2, digits.toScientific(8, 1));
+        verifyDigitList(
+                "18628300",
+                digits);
+    }
+    {
+        digits.set(43561);
+        assertEquals("", 6, digits.toScientific(-1, 3));
+        verifyDigitList(
+                ".043561",
+                digits);
+    }
+    {
+        digits.set(43561);
+        assertEquals("", 3, digits.toScientific(0, 3));
+        verifyDigitList(
+                "43.561",
+                digits);
+    }
+    {
+        digits.set(43561);
+        assertEquals("", 3, digits.toScientific(2, 3));
+        verifyDigitList(
+                "43.561",
+                digits);
+    }
+    {
+        digits.set(43561);
+        assertEquals("", 0, digits.toScientific(3, 3));
+        verifyDigitList(
+                "43561",
+                digits);
+    }
+    {
+        digits.set(43561);
+        assertEquals("", 0, digits.toScientific(5, 3));
+        verifyDigitList(
+                "43561",
+                digits);
+    }
+    {
+        digits.set(43561);
+        assertEquals("", -3, digits.toScientific(6, 3));
+        verifyDigitList(
+                "43561000",
+                digits);
+    }
+    {
+        digits.set(43561);
+        assertEquals("", -3, digits.toScientific(8, 3));
+        verifyDigitList(
+                "43561000",
+                digits);
+    }
+    {
+        digits.set(43561);
+        assertEquals("", -6, digits.toScientific(9, 3));
+        verifyDigitList(
+                "43561000000",
+                digits);
+    }
+}
+
+void NumberFormat2Test::TestLowerUpperExponent() {
+    DigitList digits;
+
+    digits.set(98.7);
+    assertEquals("", -1, digits.getLowerExponent());
+    assertEquals("", 2, digits.getUpperExponent());
+}
+
+void NumberFormat2Test::TestRounding() {
+    DigitList digits;
+    uprv_decContextSetRounding(&digits.fContext, DEC_ROUND_CEILING);
+    {
+        // Round at very large exponent
+        digits.set(789.123);
+        digits.roundAtExponent(100);
+        verifyDigitList(
+                "10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", // 100 0's after 1
+                digits);
+    }
+    {
+        // Round at very large exponent
+        digits.set(789.123);
+        digits.roundAtExponent(1);
+        verifyDigitList(
+                "790", // 100 0's after 1
+                digits);
+    }
+    {
+        // Round at positive exponent
+        digits.set(789.123);
+        digits.roundAtExponent(1);
+        verifyDigitList("790", digits);
+    }
+    {
+        // Round at zero exponent
+        digits.set(788.123);
+        digits.roundAtExponent(0);
+        verifyDigitList("789", digits);
+    }
+    {
+        // Round at negative exponent
+        digits.set(789.123);
+        digits.roundAtExponent(-2);
+        verifyDigitList("789.13", digits);
+    }
+    {
+        // Round to exponent of digits.
+        digits.set(789.123);
+        digits.roundAtExponent(-3);
+        verifyDigitList("789.123", digits);
+    }
+    {
+        // Round at large negative exponent
+        digits.set(789.123);
+        digits.roundAtExponent(-100);
+        verifyDigitList("789.123", digits);
+    }
+    {
+        // Round negative
+        digits.set(-789.123);
+        digits.roundAtExponent(-2);
+        digits.setPositive(TRUE);
+        verifyDigitList("789.12", digits);
+    }
+    {
+        // Round to 1 significant digit
+        digits.set(789.123);
+        digits.roundAtExponent(INT32_MIN, 1);
+        verifyDigitList("800", digits);
+    }
+    {
+        // Round to 5 significant digit
+        digits.set(789.123);
+        digits.roundAtExponent(INT32_MIN, 5);
+        verifyDigitList("789.13", digits);
+    }
+    {
+        // Round to 6 significant digit
+        digits.set(789.123);
+        digits.roundAtExponent(INT32_MIN, 6);
+        verifyDigitList("789.123", digits);
+    }
+    {
+        // no-op
+        digits.set(789.123);
+        digits.roundAtExponent(INT32_MIN, INT32_MAX);
+        verifyDigitList("789.123", digits);
+    }
+    {
+        // Rounding at -1 produces fewer than 5 significant digits
+        digits.set(789.123);
+        digits.roundAtExponent(-1, 5);
+        verifyDigitList("789.2", digits);
+    }
+    {
+        // Rounding at -1 produces exactly 4 significant digits
+        digits.set(789.123);
+        digits.roundAtExponent(-1, 4);
+        verifyDigitList("789.2", digits);
+    }
+    {
+        // Rounding at -1 produces more than 3 significant digits
+        digits.set(788.123);
+        digits.roundAtExponent(-1, 3);
+        verifyDigitList("789", digits);
+    }
+    {
+        digits.set(123.456);
+        digits.round(INT32_MAX);
+        verifyDigitList("123.456", digits);
+    }
+    {
+        digits.set(123.456);
+        digits.round(1);
+        verifyDigitList("200", digits);
+    }
+}
+void NumberFormat2Test::TestBenchmark() {
+/*
+    UErrorCode status = U_ZERO_ERROR;
+    Locale en("en");
+    DecimalFormatSymbols *sym = new DecimalFormatSymbols(en, status);
+    DecimalFormat2 fmt(en, "0.0000000", status);
+    FieldPosition fpos(0);
+    clock_t start = clock();
+    for (int32_t i = 0; i < 100000; ++i) {
+       UParseError perror;
+       DecimalFormat2 fmt2("0.0000000", new DecimalFormatSymbols(*sym), perror, status);
+//       UnicodeString append;
+//       fmt.format(4.6692016, append, fpos, status);
+    }
+    errln("Took %f", (double) (clock() - start) / CLOCKS_PER_SEC);
+    assertSuccess("", status);
+*/
+}
+
+void NumberFormat2Test::TestBenchmark2() {
+/*
+    UErrorCode status = U_ZERO_ERROR;
+    Locale en("en");
+    DecimalFormatSymbols *sym = new DecimalFormatSymbols(en, status);
+    DecimalFormat fmt("0.0000000", sym, status);
+    FieldPosition fpos(0);
+    clock_t start = clock();
+    for (int32_t i = 0; i < 100000; ++i) {
+      UParseError perror;
+      DecimalFormat fmt("0.0000000", new DecimalFormatSymbols(*sym), perror, status);
+//        UnicodeString append;
+//        fmt.format(4.6692016, append, fpos, status);
+    }
+    errln("Took %f", (double) (clock() - start) / CLOCKS_PER_SEC);
+    assertSuccess("", status);
+*/
+}
+
+void NumberFormat2Test::TestSmallIntFormatter() {
+    verifySmallIntFormatter("0", 7, 0, -2);
+    verifySmallIntFormatter("7", 7, 1, -2);
+    verifySmallIntFormatter("07", 7, 2, -2);
+    verifySmallIntFormatter("07", 7, 2, 2);
+    verifySmallIntFormatter("007", 7, 3, 4);
+    verifySmallIntFormatter("7", 7, -1, 3);
+    verifySmallIntFormatter("0", 0, -1, 3);
+    verifySmallIntFormatter("057", 57, 3, 7);
+    verifySmallIntFormatter("0057", 57, 4, 7);
+    // too many digits for small int
+    verifySmallIntFormatter("", 57, 5, 7);
+    // too many digits for small int
+    verifySmallIntFormatter("", 57, 5, 4);
+    verifySmallIntFormatter("03", 3, 2, 3);
+    verifySmallIntFormatter("32", 32, 2, 3);
+    verifySmallIntFormatter("321", 321, 2, 3);
+    verifySmallIntFormatter("219", 3219, 2, 3);
+    verifySmallIntFormatter("4095", 4095, 2, 4);
+    verifySmallIntFormatter("4095", 4095, 2, 5);
+    verifySmallIntFormatter("", 4096, 2, 5);
+}
+
+void NumberFormat2Test::TestPositiveIntDigitFormatter() {
+    DigitFormatter formatter;
+    {
+        NumberFormat2Test_Attributes expectedAttributes[] = {
+            {UNUM_INTEGER_FIELD, 0, 4},
+            {0, -1, 0}};
+        verifyPositiveIntDigitFormatter(
+                "0057",
+                formatter,
+                57,
+                4,
+                INT32_MAX,
+                expectedAttributes);
+    }
+    {
+        NumberFormat2Test_Attributes expectedAttributes[] = {
+            {UNUM_INTEGER_FIELD, 0, 5},
+            {0, -1, 0}};
+        verifyPositiveIntDigitFormatter(
+                "00057",
+                formatter,
+                57,
+                5,
+                INT32_MAX,
+                expectedAttributes);
+    }
+    {
+        NumberFormat2Test_Attributes expectedAttributes[] = {
+            {UNUM_INTEGER_FIELD, 0, 5},
+            {0, -1, 0}};
+        verifyPositiveIntDigitFormatter(
+                "01000",
+                formatter,
+                1000,
+                5,
+                INT32_MAX,
+                expectedAttributes);
+    }
+    {
+        NumberFormat2Test_Attributes expectedAttributes[] = {
+            {UNUM_INTEGER_FIELD, 0, 3},
+            {0, -1, 0}};
+        verifyPositiveIntDigitFormatter(
+                "100",
+                formatter,
+                100,
+                0,
+                INT32_MAX,
+                expectedAttributes);
+    }
+    {
+        NumberFormat2Test_Attributes expectedAttributes[] = {
+            {UNUM_INTEGER_FIELD, 0, 10},
+            {0, -1, 0}};
+        verifyPositiveIntDigitFormatter(
+                "2147483647",
+                formatter,
+                2147483647,
+                5,
+                INT32_MAX,
+                expectedAttributes);
+    }
+    {
+        NumberFormat2Test_Attributes expectedAttributes[] = {
+            {UNUM_INTEGER_FIELD, 0, 12},
+            {0, -1, 0}};
+        verifyPositiveIntDigitFormatter(
+                "002147483647",
+                formatter,
+                2147483647,
+                12,
+                INT32_MAX,
+                expectedAttributes);
+    }
+    {
+        // Test long digit string where we have to append one
+        // character at a time.
+        NumberFormat2Test_Attributes expectedAttributes[] = {
+            {UNUM_INTEGER_FIELD, 0, 40},
+            {0, -1, 0}};
+        verifyPositiveIntDigitFormatter(
+                "0000000000000000000000000000002147483647",
+                formatter,
+                2147483647,
+                40,
+                INT32_MAX,
+                expectedAttributes);
+    }
+    {
+        NumberFormat2Test_Attributes expectedAttributes[] = {
+            {UNUM_INTEGER_FIELD, 0, 4},
+            {0, -1, 0}};
+        verifyPositiveIntDigitFormatter(
+                "6283",
+                formatter,
+                186283,
+                2,
+                4,
+                expectedAttributes);
+    }
+    {
+        NumberFormat2Test_Attributes expectedAttributes[] = {
+            {UNUM_INTEGER_FIELD, 0, 1},
+            {0, -1, 0}};
+        verifyPositiveIntDigitFormatter(
+                "0",
+                formatter,
+                186283,
+                0,
+                0,
+                expectedAttributes);
+    }
+    {
+        NumberFormat2Test_Attributes expectedAttributes[] = {
+            {UNUM_INTEGER_FIELD, 0, 1},
+            {0, -1, 0}};
+        verifyPositiveIntDigitFormatter(
+                "3",
+                formatter,
+                186283,
+                1,
+                1,
+                expectedAttributes);
+    }
+}
+
+
+void NumberFormat2Test::TestDigitFormatterDefaultCtor() {
+    DigitFormatter formatter;
+    VisibleDigits digits;
+    FixedPrecision precision;
+    UErrorCode status = U_ZERO_ERROR;
+    precision.initVisibleDigits(246.801, digits, status);
+    assertSuccess("", status);
+    DigitGrouping grouping;
+    DigitFormatterOptions options;
+    verifyDigitFormatter(
+            "246.801",
+            formatter,
+            digits,
+            grouping,
+            options,
+            NULL);
+}
+
+void NumberFormat2Test::TestDigitFormatterMonetary() {
+    UErrorCode status = U_ZERO_ERROR;
+    DecimalFormatSymbols symbols("en", status);
+    if (!assertSuccess("", status)) {
+        return;
+    }
+    symbols.setSymbol(
+            DecimalFormatSymbols::kMonetarySeparatorSymbol,
+            "decimal separator");
+    symbols.setSymbol(
+            DecimalFormatSymbols::kMonetaryGroupingSeparatorSymbol,
+            "grouping separator");
+    DigitFormatter formatter(symbols);
+    VisibleDigits visibleDigits;
+    DigitGrouping grouping;
+    FixedPrecision precision;
+    precision.initVisibleDigits(43560.02, visibleDigits, status);
+    if (!assertSuccess("", status)) {
+        return;
+    }
+    DigitFormatterOptions options;
+    grouping.fGrouping = 3;
+    {
+        verifyDigitFormatter(
+                "43,560.02",
+                formatter,
+                visibleDigits,
+                grouping,
+                options,
+                NULL);
+        formatter.setDecimalFormatSymbolsForMonetary(symbols);
+        verifyDigitFormatter(
+                "43grouping separator560decimal separator02",
+                formatter,
+                visibleDigits,
+                grouping,
+                options,
+                NULL);
+    }
+}
+
+void NumberFormat2Test::TestDigitFormatter() {
+    UErrorCode status = U_ZERO_ERROR;
+    DecimalFormatSymbols symbols("en", status);
+    if (!assertSuccess("", status)) {
+        return;
+    }
+    DigitFormatter formatter(symbols);
+    DigitInterval interval;
+    {
+        VisibleDigits visibleDigits;
+        DigitGrouping grouping;
+        FixedPrecision precision;
+        precision.initVisibleDigits((int64_t) 8192, visibleDigits, status);
+        if (!assertSuccess("", status)) {
+            return;
+        }
+        DigitFormatterOptions options;
+        verifyDigitFormatter(
+                "8192",
+                formatter,
+                visibleDigits,
+                grouping,
+                options,
+                NULL);
+        NumberFormat2Test_Attributes expectedAttributes[] = {
+            {UNUM_INTEGER_FIELD, 0, 4},
+            {UNUM_DECIMAL_SEPARATOR_FIELD, 4, 5},
+            {0, -1, 0}};
+        options.fAlwaysShowDecimal = TRUE;
+        verifyDigitFormatter(
+                "8192.",
+                formatter,
+                visibleDigits,
+                grouping,
+                options,
+                expectedAttributes);
+
+        // Turn on grouping
+        grouping.fGrouping = 3;
+        options.fAlwaysShowDecimal = FALSE;
+        verifyDigitFormatter(
+                "8,192",
+                formatter,
+                visibleDigits,
+                grouping,
+                options,
+                NULL);
+
+        // turn on min grouping which will suppress grouping
+        grouping.fMinGrouping = 2;
+        verifyDigitFormatter(
+                "8192",
+                formatter,
+                visibleDigits,
+                grouping,
+                options,
+                NULL);
+
+        // adding one more digit will enable grouping once again.
+        precision.initVisibleDigits((int64_t) 43560, visibleDigits, status);
+        if (!assertSuccess("", status)) {
+            return;
+        }
+        verifyDigitFormatter(
+                "43,560",
+                formatter,
+                visibleDigits,
+                grouping,
+                options,
+                NULL);
+    }
+    {
+        DigitGrouping grouping;
+        FixedPrecision precision;
+        VisibleDigits visibleDigits;
+        precision.initVisibleDigits(
+                31415926.0078125, visibleDigits, status);
+        if (!assertSuccess("", status)) {
+            return;
+        }
+        DigitFormatterOptions options;
+        verifyDigitFormatter(
+                "31415926.0078125",
+                formatter,
+                visibleDigits,
+                grouping,
+                options,
+                NULL);
+
+        // Turn on grouping with secondary.
+        grouping.fGrouping = 2;
+        grouping.fGrouping2 = 3;
+        verifyDigitFormatter(
+                "314,159,26.0078125",
+                formatter,
+                visibleDigits,
+                grouping,
+                options,
+                NULL);
+
+        // Pad with zeros by widening interval.
+        precision.fMin.setIntDigitCount(9);
+        precision.fMin.setFracDigitCount(10);
+        precision.initVisibleDigits(
+                31415926.0078125, visibleDigits, status);
+        if (!assertSuccess("", status)) {
+            return;
+        }
+        NumberFormat2Test_Attributes expectedAttributes[] = {
+            {UNUM_GROUPING_SEPARATOR_FIELD, 1, 2},
+            {UNUM_GROUPING_SEPARATOR_FIELD, 5, 6},
+            {UNUM_GROUPING_SEPARATOR_FIELD, 9, 10},
+            {UNUM_INTEGER_FIELD, 0, 12},
+            {UNUM_DECIMAL_SEPARATOR_FIELD, 12, 13},
+            {UNUM_FRACTION_FIELD, 13, 23},
+            {0, -1, 0}};
+        verifyDigitFormatter(
+                "0,314,159,26.0078125000",
+                formatter,
+                visibleDigits,
+                grouping,
+                options,
+                expectedAttributes);
+    }
+    {
+        DigitGrouping grouping;
+        FixedPrecision precision;
+        VisibleDigits visibleDigits;
+        DigitFormatterOptions options;
+        precision.fMax.setIntDigitCount(0);
+        precision.fMax.setFracDigitCount(0);
+        precision.initVisibleDigits(
+                3125.0, visibleDigits, status);
+        if (!assertSuccess("", status)) {
+            return;
+        }
+        NumberFormat2Test_Attributes expectedAttributes[] = {
+            {UNUM_INTEGER_FIELD, 0, 1},
+            {0, -1, 0}};
+        verifyDigitFormatter(
+                "0",
+                formatter,
+                visibleDigits,
+                grouping,
+                options,
+                expectedAttributes);
+        NumberFormat2Test_Attributes expectedAttributesWithDecimal[] = {
+            {UNUM_INTEGER_FIELD, 0, 1},
+            {UNUM_DECIMAL_SEPARATOR_FIELD, 1, 2},
+            {0, -1, 0}};
+        options.fAlwaysShowDecimal = TRUE;
+        verifyDigitFormatter(
+                "0.",
+                formatter,
+                visibleDigits,
+                grouping,
+                options,
+                expectedAttributesWithDecimal);
+    }
+    {
+        DigitGrouping grouping;
+        FixedPrecision precision;
+        VisibleDigits visibleDigits;
+        DigitFormatterOptions options;
+        precision.fMax.setIntDigitCount(1);
+        precision.fMin.setFracDigitCount(1);
+        precision.initVisibleDigits(
+                3125.0, visibleDigits, status);
+        if (!assertSuccess("", status)) {
+            return;
+        }
+        NumberFormat2Test_Attributes expectedAttributes[] = {
+            {UNUM_INTEGER_FIELD, 0, 1},
+            {UNUM_DECIMAL_SEPARATOR_FIELD, 1, 2},
+            {UNUM_FRACTION_FIELD, 2, 3},
+            {0, -1, 0}};
+        options.fAlwaysShowDecimal = TRUE;
+        verifyDigitFormatter(
+                "5.0",
+                formatter,
+                visibleDigits,
+                grouping,
+                options,
+                expectedAttributes);
+    }
+}
+
+void NumberFormat2Test::TestSciFormatterDefaultCtor() {
+    DigitFormatter formatter;
+    ScientificPrecision precision;
+    VisibleDigitsWithExponent visibleDigits;
+    UErrorCode status = U_ZERO_ERROR;
+    precision.initVisibleDigitsWithExponent(
+            6.02E23, visibleDigits, status);
+    if (!assertSuccess("", status)) {
+        return;
+    }
+    SciFormatterOptions options;
+    verifySciFormatter(
+            "6.02E23",
+            formatter,
+            visibleDigits,
+            options,
+            NULL);
+    precision.initVisibleDigitsWithExponent(
+            6.62E-34, visibleDigits, status);
+    if (!assertSuccess("", status)) {
+        return;
+    }
+    verifySciFormatter(
+            "6.62E-34",
+            formatter,
+            visibleDigits,
+            options,
+            NULL);
+}
+
+void NumberFormat2Test::TestSciFormatter() {
+    DigitFormatter formatter;
+    ScientificPrecision precision;
+    precision.fMantissa.fMin.setIntDigitCount(4);
+    precision.fMantissa.fMax.setIntDigitCount(4);
+    precision.fMantissa.fMin.setFracDigitCount(0);
+    precision.fMantissa.fMax.setFracDigitCount(0);
+    precision.fMinExponentDigits = 3;
+    VisibleDigitsWithExponent visibleDigits;
+    UErrorCode status = U_ZERO_ERROR;
+    precision.initVisibleDigitsWithExponent(
+            1.248E26, visibleDigits, status);
+    if (!assertSuccess("", status)) {
+        return;
+    }
+    SciFormatterOptions options;
+
+    {
+        options.fExponent.fAlwaysShowSign = TRUE;
+        NumberFormat2Test_Attributes expectedAttributes[] = {
+            {UNUM_INTEGER_FIELD, 0, 4},
+            {UNUM_EXPONENT_SYMBOL_FIELD, 4, 5},
+            {UNUM_EXPONENT_SIGN_FIELD, 5, 6},
+            {UNUM_EXPONENT_FIELD, 6, 9},
+            {0, -1, 0}};
+        verifySciFormatter(
+                "1248E+023",
+                formatter,
+                visibleDigits,
+                options,
+                expectedAttributes);
+    }
+    {
+        options.fMantissa.fAlwaysShowDecimal = TRUE;
+        options.fExponent.fAlwaysShowSign = FALSE;
+        NumberFormat2Test_Attributes expectedAttributes[] = {
+            {UNUM_INTEGER_FIELD, 0, 4},
+            {UNUM_DECIMAL_SEPARATOR_FIELD, 4, 5},
+            {UNUM_EXPONENT_SYMBOL_FIELD, 5, 6},
+            {UNUM_EXPONENT_FIELD, 6, 9},
+            {0, -1, 0}};
+        verifySciFormatter(
+                "1248.E023",
+                formatter,
+                visibleDigits,
+                options,
+                expectedAttributes);
+    }
+}
+
+void NumberFormat2Test::TestValueFormatterIsFastFormattable() {
+    UErrorCode status = U_ZERO_ERROR;
+    DecimalFormatSymbols symbols("en", status);
+    if (!assertSuccess("", status)) {
+        return;
+    }
+    DigitFormatter formatter(symbols);
+    DigitGrouping grouping;
+    FixedPrecision precision;
+    DigitFormatterOptions options;
+    ValueFormatter vf;
+    vf.prepareFixedDecimalFormatting(
+            formatter, grouping, precision, options);
+    assertTrue("", vf.isFastFormattable(0));
+    assertTrue("", vf.isFastFormattable(35));
+    assertTrue("", vf.isFastFormattable(-48));
+    assertTrue("", vf.isFastFormattable(2147483647));
+    assertTrue("", vf.isFastFormattable(-2147483647));
+    assertFalse("", vf.isFastFormattable(-2147483648L));
+    {
+        DigitGrouping grouping;
+        grouping.fGrouping = 3;
+        ValueFormatter vf;
+        vf.prepareFixedDecimalFormatting(
+                formatter, grouping, precision, options);
+        assertTrue("0", vf.isFastFormattable(0));
+        assertTrue("62", vf.isFastFormattable(62));
+        assertTrue("999", vf.isFastFormattable(999));
+        assertFalse("1000", vf.isFastFormattable(1000));
+        assertTrue("-1", vf.isFastFormattable(-1));
+        assertTrue("-38", vf.isFastFormattable(-38));
+        assertTrue("-999", vf.isFastFormattable(-999));
+        assertFalse("-1000", vf.isFastFormattable(-1000));
+        grouping.fMinGrouping = 2;
+        assertTrue("-1000", vf.isFastFormattable(-1000));
+        assertTrue("-4095", vf.isFastFormattable(-4095));
+        assertTrue("4095", vf.isFastFormattable(4095));
+        // We give up on acounting digits at 4096
+        assertFalse("-4096", vf.isFastFormattable(-4096));
+        assertFalse("4096", vf.isFastFormattable(4096));
+    }
+    {
+        // grouping on but with max integer digits set.
+        DigitGrouping grouping;
+        grouping.fGrouping = 4;
+        FixedPrecision precision;
+        precision.fMax.setIntDigitCount(4);
+        ValueFormatter vf;
+        vf.prepareFixedDecimalFormatting(
+                formatter, grouping, precision, options);
+        assertTrue("-4096", vf.isFastFormattable(-4096));
+        assertTrue("4096", vf.isFastFormattable(4096));
+        assertTrue("-10000", vf.isFastFormattable(-10000));
+        assertTrue("10000", vf.isFastFormattable(10000));
+        assertTrue("-2147483647", vf.isFastFormattable(-2147483647));
+        assertTrue("2147483647", vf.isFastFormattable(2147483647));
+
+        precision.fMax.setIntDigitCount(5);
+        assertFalse("-4096", vf.isFastFormattable(-4096));
+        assertFalse("4096", vf.isFastFormattable(4096));
+
+    }
+    {
+        // grouping on but with min integer digits set.
+        DigitGrouping grouping;
+        grouping.fGrouping = 3;
+        FixedPrecision precision;
+        precision.fMin.setIntDigitCount(3);
+        ValueFormatter vf;
+        vf.prepareFixedDecimalFormatting(
+                formatter, grouping, precision, options);
+        assertTrue("-999", vf.isFastFormattable(-999));
+        assertTrue("999", vf.isFastFormattable(999));
+        assertFalse("-1000", vf.isFastFormattable(-1000));
+        assertFalse("1000", vf.isFastFormattable(1000));
+
+        precision.fMin.setIntDigitCount(4);
+        assertFalse("-999", vf.isFastFormattable(-999));
+        assertFalse("999", vf.isFastFormattable(999));
+        assertFalse("-2147483647", vf.isFastFormattable(-2147483647));
+        assertFalse("2147483647", vf.isFastFormattable(2147483647));
+    }
+    {
+        // options set.
+        DigitFormatterOptions options;
+        ValueFormatter vf;
+        vf.prepareFixedDecimalFormatting(
+                formatter, grouping, precision, options);
+        assertTrue("5125", vf.isFastFormattable(5125));
+        options.fAlwaysShowDecimal = TRUE;
+        assertFalse("5125", vf.isFastFormattable(5125));
+        options.fAlwaysShowDecimal = FALSE;
+        assertTrue("5125", vf.isFastFormattable(5125));
+    }
+    {
+        // test fraction digits
+        FixedPrecision precision;
+        ValueFormatter vf;
+        vf.prepareFixedDecimalFormatting(
+                formatter, grouping, precision, options);
+        assertTrue("7127", vf.isFastFormattable(7127));
+        precision.fMin.setFracDigitCount(1);
+        assertFalse("7127", vf.isFastFormattable(7127));
+    }
+    {
+        // test presence of significant digits
+        FixedPrecision precision;
+        ValueFormatter vf;
+        vf.prepareFixedDecimalFormatting(
+                formatter, grouping, precision, options);
+        assertTrue("1049", vf.isFastFormattable(1049));
+        precision.fSignificant.setMin(1);
+        assertFalse("1049", vf.isFastFormattable(1049));
+    }
+    {
+        // test presence of rounding increment
+        FixedPrecision precision;
+        ValueFormatter vf;
+        vf.prepareFixedDecimalFormatting(
+                formatter, grouping, precision, options);
+        assertTrue("1099", vf.isFastFormattable(1099));
+        precision.fRoundingIncrement.set(2.3);
+        assertFalse("1099", vf.isFastFormattable(1099));
+    }
+    {
+        // test scientific notation
+        ScientificPrecision precision;
+        SciFormatterOptions options;
+        ValueFormatter vf;
+        vf.prepareScientificFormatting(
+                formatter, precision, options);
+        assertFalse("1081", vf.isFastFormattable(1081));
+    }
+}
+
+void NumberFormat2Test::TestDigitAffix() {
+    DigitAffix affix;
+    {
+        affix.append("foo");
+        affix.append("--", UNUM_SIGN_FIELD);
+        affix.append("%", UNUM_PERCENT_FIELD);
+        NumberFormat2Test_Attributes expectedAttributes[] = {
+            {UNUM_SIGN_FIELD, 3, 5},
+            {UNUM_PERCENT_FIELD, 5, 6},
+            {0, -1, 0}};
+        verifyAffix("foo--%", affix, expectedAttributes);
+    }
+    {
+        affix.remove();
+        affix.append("USD", UNUM_CURRENCY_FIELD);
+        affix.append(" ");
+        NumberFormat2Test_Attributes expectedAttributes[] = {
+            {UNUM_CURRENCY_FIELD, 0, 3},
+            {0, -1, 0}};
+        verifyAffix("USD ", affix, expectedAttributes);
+    }
+    {
+        affix.setTo("%%", UNUM_PERCENT_FIELD);
+        NumberFormat2Test_Attributes expectedAttributes[] = {
+            {UNUM_PERCENT_FIELD, 0, 2},
+            {0, -1, 0}};
+        verifyAffix("%%", affix, expectedAttributes);
+    }
+}
+
+void NumberFormat2Test::TestPluralAffix() {
+    UErrorCode status = U_ZERO_ERROR;
+    PluralAffix part;
+    part.setVariant("one", "Dollar", status);
+    part.setVariant("few", "DollarFew", status);
+    part.setVariant("other", "Dollars", status);
+    PluralAffix dollar(part);
+    PluralAffix percent(part);
+    part.remove();
+    part.setVariant("one", "Percent", status);
+    part.setVariant("many", "PercentMany", status);
+    part.setVariant("other", "Percents", status);
+    percent = part;
+    part.remove();
+    part.setVariant("one", "foo", status);
+
+    PluralAffix pa;
+    assertEquals("", "", pa.getOtherVariant().toString());
+    pa.append(dollar, UNUM_CURRENCY_FIELD, status);
+    pa.append(" and ");
+    pa.append(percent, UNUM_PERCENT_FIELD, status);
+    pa.append("-", UNUM_SIGN_FIELD);
+
+    {
+        // other
+        NumberFormat2Test_Attributes expectedAttributes[] = {
+            {UNUM_CURRENCY_FIELD, 0, 7},
+            {UNUM_PERCENT_FIELD, 12, 20},
+            {UNUM_SIGN_FIELD, 20, 21},
+            {0, -1, 0}};
+        verifyAffix(
+                "Dollars and Percents-",
+                pa.getByCategory("other"),
+                expectedAttributes);
+    }
+    {
+        // two which is same as other
+        NumberFormat2Test_Attributes expectedAttributes[] = {
+            {UNUM_CURRENCY_FIELD, 0, 7},
+            {UNUM_PERCENT_FIELD, 12, 20},
+            {UNUM_SIGN_FIELD, 20, 21},
+            {0, -1, 0}};
+        verifyAffix(
+                "Dollars and Percents-",
+                pa.getByCategory("two"),
+                expectedAttributes);
+    }
+    {
+        // bad which is same as other
+        NumberFormat2Test_Attributes expectedAttributes[] = {
+            {UNUM_CURRENCY_FIELD, 0, 7},
+            {UNUM_PERCENT_FIELD, 12, 20},
+            {UNUM_SIGN_FIELD, 20, 21},
+            {0, -1, 0}};
+        verifyAffix(
+                "Dollars and Percents-",
+                pa.getByCategory("bad"),
+                expectedAttributes);
+    }
+    {
+        // one
+        NumberFormat2Test_Attributes expectedAttributes[] = {
+            {UNUM_CURRENCY_FIELD, 0, 6},
+            {UNUM_PERCENT_FIELD, 11, 18},
+            {UNUM_SIGN_FIELD, 18, 19},
+            {0, -1, 0}};
+        verifyAffix(
+                "Dollar and Percent-",
+                pa.getByCategory("one"),
+                expectedAttributes);
+    }
+    {
+        // few
+        NumberFormat2Test_Attributes expectedAttributes[] = {
+            {UNUM_CURRENCY_FIELD, 0, 9},
+            {UNUM_PERCENT_FIELD, 14, 22},
+            {UNUM_SIGN_FIELD, 22, 23},
+            {0, -1, 0}};
+        verifyAffix(
+                "DollarFew and Percents-",
+                pa.getByCategory("few"),
+                expectedAttributes);
+    }
+    {
+        // many
+        NumberFormat2Test_Attributes expectedAttributes[] = {
+            {UNUM_CURRENCY_FIELD, 0, 7},
+            {UNUM_PERCENT_FIELD, 12, 23},
+            {UNUM_SIGN_FIELD, 23, 24},
+            {0, -1, 0}};
+        verifyAffix(
+                "Dollars and PercentMany-",
+                pa.getByCategory("many"),
+                expectedAttributes);
+    }
+    assertTrue("", pa.hasMultipleVariants());
+    pa.remove();
+    pa.append("$$$", UNUM_CURRENCY_FIELD);
+    assertFalse("", pa.hasMultipleVariants());
+    
+}
+
+void NumberFormat2Test::TestCurrencyAffixInfo() {
+    CurrencyAffixInfo info;
+    assertTrue("", info.isDefault());
+    UnicodeString expectedSymbol("\\u00a4");
+    UnicodeString expectedSymbolIso("\\u00a4\\u00a4");
+    UnicodeString expectedSymbols("\\u00a4\\u00a4\\u00a4");
+    assertEquals("", expectedSymbol.unescape(), info.getSymbol());
+    assertEquals("", expectedSymbolIso.unescape(), info.getISO());
+    assertEquals("", expectedSymbols.unescape(), info.getLong().getByCategory("one").toString());
+    assertEquals("", expectedSymbols.unescape(), info.getLong().getByCategory("other").toString());
+    assertEquals("", expectedSymbols.unescape(), info.getLong().getByCategory("two").toString());
+    UErrorCode status = U_ZERO_ERROR;
+    static UChar USD[] = {0x55, 0x53, 0x44, 0x0};
+    LocalPointer<PluralRules> rules(PluralRules::forLocale("en", status));
+    if (!assertSuccess("", status)) {
+        return;
+    }
+    info.set("en", rules.getAlias(), USD, status);
+    assertEquals("", "$", info.getSymbol(), TRUE);
+    assertEquals("", "USD", info.getISO(), TRUE);
+    assertEquals("", "US dollar", info.getLong().getByCategory("one").toString(), TRUE);
+    assertEquals("", "US dollars", info.getLong().getByCategory("other").toString(), TRUE);
+    assertEquals("", "US dollars", info.getLong().getByCategory("two").toString(), TRUE);
+    assertFalse("", info.isDefault());
+    info.set(NULL, NULL, NULL, status);
+    assertTrue("", info.isDefault());
+    assertEquals("", expectedSymbol.unescape(), info.getSymbol());
+    assertEquals("", expectedSymbolIso.unescape(), info.getISO());
+    assertEquals("", expectedSymbols.unescape(), info.getLong().getByCategory("one").toString());
+    assertEquals("", expectedSymbols.unescape(), info.getLong().getByCategory("other").toString());
+    assertEquals("", expectedSymbols.unescape(), info.getLong().getByCategory("two").toString());
+    info.setSymbol("$");
+    assertFalse("", info.isDefault());
+    info.set(NULL, NULL, NULL, status);
+    assertTrue("", info.isDefault());
+    info.setISO("USD");
+    assertFalse("", info.isDefault());
+    assertSuccess("", status);
+}
+
+void NumberFormat2Test::TestAffixPattern() {
+    static UChar chars[500];
+    for (int32_t i = 0; i < UPRV_LENGTHOF(chars); ++i) {
+        chars[i] = (UChar) (i + 1);
+    }
+    AffixPattern first;
+    first.add(AffixPattern::kPercent);
+    first.addLiteral(chars, 0, 200);
+    first.addLiteral(chars, 200, 300);
+    first.addCurrency(2);
+    first.addLiteral(chars, 0, 256);
+    AffixPattern second;
+    second.add(AffixPattern::kPercent);
+    second.addLiteral(chars, 0, 300);
+    second.addLiteral(chars, 300, 200);
+    second.addCurrency(2);
+    second.addLiteral(chars, 0, 150);
+    second.addLiteral(chars, 150, 106);
+    assertTrue("", first.equals(second));
+    AffixPatternIterator iter;
+    second.remove();
+    assertFalse("", second.iterator(iter).nextToken());
+    assertTrue("", first.iterator(iter).nextToken());
+    assertEquals("", AffixPattern::kPercent, iter.getTokenType());
+    assertEquals("", 1, iter.getTokenLength());
+    assertTrue("", iter.nextToken());
+    UnicodeString str;
+    assertEquals("", 500, iter.getLiteral(str).length());
+    assertEquals("", AffixPattern::kLiteral, iter.getTokenType());
+    assertEquals("", 500, iter.getTokenLength());
+    assertTrue("", iter.nextToken());
+    assertEquals("", AffixPattern::kCurrency, iter.getTokenType());
+    assertEquals("", 2, iter.getTokenLength());
+    assertTrue("", iter.nextToken());
+    assertEquals("", 256, iter.getLiteral(str).length());
+    assertEquals("", AffixPattern::kLiteral, iter.getTokenType());
+    assertEquals("", 256, iter.getTokenLength());
+    assertFalse("", iter.nextToken());
+}
+
+void NumberFormat2Test::TestAffixPatternDoubleQuote() {
+    UnicodeString str("'Don''t'");
+    AffixPattern expected;
+    // Don't
+    static UChar chars[] = {0x44, 0x6F, 0x6E, 0x27, 0x74};
+    expected.addLiteral(chars, 0, UPRV_LENGTHOF(chars));
+    AffixPattern actual;
+    UErrorCode status = U_ZERO_ERROR;
+    AffixPattern::parseUserAffixString(str, actual, status);
+    assertTrue("", expected.equals(actual));
+    UnicodeString formattedString;
+    assertEquals("", "Don''t", actual.toUserString(formattedString));
+    assertSuccess("", status);
+}
+
+void NumberFormat2Test::TestAffixPatternParser() {
+    UErrorCode status = U_ZERO_ERROR;
+    static UChar USD[] = {0x55, 0x53, 0x44, 0x0};
+    LocalPointer<PluralRules> rules(PluralRules::forLocale("en", status));
+    DecimalFormatSymbols symbols("en", status);
+    if (U_FAILURE(status)) {
+        dataerrln("Error creating DecimalFormatSymbols - %s", u_errorName(status));
+        return;
+    }
+    AffixPatternParser parser(symbols);
+    CurrencyAffixInfo currencyAffixInfo;
+    currencyAffixInfo.set("en", rules.getAlias(), USD, status);
+    PluralAffix affix;
+    UnicodeString str("'--y'''dz'%'\\u00a4\\u00a4\\u00a4\\u00a4 y '\\u00a4\\u00a4\\u00a4 or '\\u00a4\\u00a4 but '\\u00a4");
+    str = str.unescape();
+    assertSuccess("", status);
+    AffixPattern affixPattern;
+    parser.parse(
+            AffixPattern::parseAffixString(str, affixPattern, status),
+            currencyAffixInfo,
+            affix,
+            status);
+    UnicodeString formattedStr;
+    affixPattern.toString(formattedStr);
+    UnicodeString expectedFormattedStr("'--y''dz'%'\\u00a4\\u00a4\\u00a4\\u00a4 y '\\u00a4\\u00a4\\u00a4 or '\\u00a4\\u00a4 but '\\u00a4");
+    expectedFormattedStr = expectedFormattedStr.unescape();
+    assertEquals("1", expectedFormattedStr, formattedStr);
+    AffixPattern userAffixPattern;
+    UnicodeString userStr("-'-'y'''d'z%\\u00a4\\u00a4\\u00a4'\\u00a4' y \\u00a4\\u00a4\\u00a4 or \\u00a4\\u00a4 but \\u00a4");
+    userStr = userStr.unescape();
+    AffixPattern::parseUserAffixString(userStr, userAffixPattern, status),
+    assertTrue("", affixPattern.equals(userAffixPattern));
+    AffixPattern userAffixPattern2;
+    UnicodeString formattedUserStr;
+    AffixPattern::parseUserAffixString(
+            userAffixPattern.toUserString(formattedUserStr),
+            userAffixPattern2,
+            status);
+    UnicodeString expectedFormattedUserStr(
+            "-'-'y''dz%\\u00a4\\u00a4\\u00a4'\\u00a4' y \\u00a4\\u00a4\\u00a4 or \\u00a4\\u00a4 but \\u00a4");
+    assertEquals("2", expectedFormattedUserStr.unescape(), formattedUserStr);
+    assertTrue("", userAffixPattern2.equals(userAffixPattern));
+    assertSuccess("", status);
+    assertTrue("", affixPattern.usesCurrency());
+    assertTrue("", affixPattern.usesPercent());
+    assertFalse("", affixPattern.usesPermill());
+    assertTrue("", affix.hasMultipleVariants());
+    {
+        // other
+        NumberFormat2Test_Attributes expectedAttributes[] = {
+            {UNUM_SIGN_FIELD, 0, 1},
+            {UNUM_PERCENT_FIELD, 6, 7},
+            {UNUM_CURRENCY_FIELD, 7, 17},
+            {UNUM_CURRENCY_FIELD, 21, 31},
+            {UNUM_CURRENCY_FIELD, 35, 38},
+            {UNUM_CURRENCY_FIELD, 43, 44},
+            {0, -1, 0}};
+        verifyAffix(
+                "--y'dz%US dollars\\u00a4 y US dollars or USD but $",
+                affix.getByCategory("other"),
+                expectedAttributes);
+    }
+    {
+        // one
+        NumberFormat2Test_Attributes expectedAttributes[] = {
+            {UNUM_SIGN_FIELD, 0, 1},
+            {UNUM_PERCENT_FIELD, 6, 7},
+            {UNUM_CURRENCY_FIELD, 7, 16},
+            {UNUM_CURRENCY_FIELD, 20, 29},
+            {UNUM_CURRENCY_FIELD, 33, 36},
+            {UNUM_CURRENCY_FIELD, 41, 42},
+            {0, -1, 0}};
+        verifyAffix(
+                "--y'dz%US dollar\\u00a4 y US dollar or USD but $",
+                affix.getByCategory("one"),
+                expectedAttributes);
+    }
+    affix.remove();
+    str = "%'-";
+    affixPattern.remove();
+    parser.parse(
+            AffixPattern::parseAffixString(str, affixPattern, status),
+            currencyAffixInfo,
+            affix,
+            status);
+    assertSuccess("", status);
+    assertFalse("", affixPattern.usesCurrency());
+    assertFalse("", affixPattern.usesPercent());
+    assertFalse("", affixPattern.usesPermill());
+    assertFalse("", affix.hasMultipleVariants());
+    {
+        // other
+        NumberFormat2Test_Attributes expectedAttributes[] = {
+            {UNUM_SIGN_FIELD, 1, 2},
+            {0, -1, 0}};
+        verifyAffix(
+                "%-",
+                affix.getByCategory("other"),
+                expectedAttributes);
+    }
+    UnicodeString a4("\\u00a4");
+    AffixPattern scratchPattern;
+    AffixPattern::parseAffixString(a4.unescape(), scratchPattern, status);
+    assertFalse("", scratchPattern.usesCurrency());
+
+    // Test really long string > 256 chars.
+    str = "'\\u2030012345678901234567890123456789012345678901234567890123456789"
+          "012345678901234567890123456789012345678901234567890123456789"
+          "012345678901234567890123456789012345678901234567890123456789"
+          "012345678901234567890123456789012345678901234567890123456789"
+          "012345678901234567890123456789012345678901234567890123456789";
+    str = str.unescape();
+    affixPattern.remove();
+    affix.remove();
+    parser.parse(
+            AffixPattern::parseAffixString(str, affixPattern, status),
+            currencyAffixInfo,
+            affix,
+            status);
+    assertSuccess("", status);
+    assertFalse("", affixPattern.usesCurrency());
+    assertFalse("", affixPattern.usesPercent());
+    assertTrue("", affixPattern.usesPermill());
+    assertFalse("", affix.hasMultipleVariants());
+    {
+       UnicodeString expected =
+           "\\u2030012345678901234567890123456789012345678901234567890123456789"
+           "012345678901234567890123456789012345678901234567890123456789"
+           "012345678901234567890123456789012345678901234567890123456789"
+           "012345678901234567890123456789012345678901234567890123456789"
+           "012345678901234567890123456789012345678901234567890123456789";
+        expected = expected.unescape();
+        NumberFormat2Test_Attributes expectedAttributes[] = {
+            {UNUM_PERMILL_FIELD, 0, 1},
+            {0, -1, 0}};
+        verifyAffix(
+                expected,
+                affix.getOtherVariant(),
+                expectedAttributes);
+    }
+}
+
+void NumberFormat2Test::TestAffixPatternAppend() {
+  AffixPattern pattern;
+  UErrorCode status = U_ZERO_ERROR;
+  UnicodeString patternStr("%\\u2030");
+  AffixPattern::parseUserAffixString(
+          patternStr.unescape(), pattern, status);
+
+  AffixPattern appendPattern;
+  UnicodeString appendPatternStr("-\\u00a4\\u00a4*");
+  AffixPattern::parseUserAffixString(
+          appendPatternStr.unescape(), appendPattern, status);
+
+  AffixPattern expectedPattern;
+  UnicodeString expectedPatternStr("%\\u2030-\\u00a4\\u00a4*");
+  AffixPattern::parseUserAffixString(
+          expectedPatternStr.unescape(), expectedPattern, status);
+  
+  assertTrue("", pattern.append(appendPattern).equals(expectedPattern));
+  assertSuccess("", status);
+}
+
+void NumberFormat2Test::TestAffixPatternAppendAjoiningLiterals() {
+  AffixPattern pattern;
+  UErrorCode status = U_ZERO_ERROR;
+  UnicodeString patternStr("%baaa");
+  AffixPattern::parseUserAffixString(
+          patternStr, pattern, status);
+
+  AffixPattern appendPattern;
+  UnicodeString appendPatternStr("caa%");
+  AffixPattern::parseUserAffixString(
+          appendPatternStr, appendPattern, status);
+
+  AffixPattern expectedPattern;
+  UnicodeString expectedPatternStr("%baaacaa%");
+  AffixPattern::parseUserAffixString(
+          expectedPatternStr, expectedPattern, status);
+  
+  assertTrue("", pattern.append(appendPattern).equals(expectedPattern));
+  assertSuccess("", status);
+}
+
+void NumberFormat2Test::TestLargeIntValue() {
+    VisibleDigits digits;
+    {
+        UErrorCode status = U_ZERO_ERROR;
+        FixedPrecision precision;
+
+        // Last 18 digits for int values.
+        verifyIntValue(
+                223372036854775807LL, 
+                precision.initVisibleDigits(INT64_MAX, digits, status));
+        assertSuccess("INT64_MAX", status);
+    }
+    {
+        UErrorCode status = U_ZERO_ERROR;
+        FixedPrecision precision;
+        precision.fMax.setIntDigitCount(5);
+
+        // Last 18 digits for int values.
+        verifyIntValue(
+                75807LL, 
+                precision.initVisibleDigits(INT64_MAX, digits, status));
+        verifySource(75807.0, digits);
+        assertSuccess("75807", status);
+    }
+    {
+        UErrorCode status = U_ZERO_ERROR;
+        FixedPrecision precision;
+
+        // Last 18 digits for int values.
+        verifyIntValue(
+                223372036854775808LL, 
+                precision.initVisibleDigits(INT64_MIN, digits, status));
+        assertSuccess("INT64_MIN", status);
+    }
+    {
+        UErrorCode status = U_ZERO_ERROR;
+        FixedPrecision precision;
+        precision.fMax.setIntDigitCount(5);
+
+        // Last 18 digits for int values.
+        verifyIntValue(
+                75808LL, 
+                precision.initVisibleDigits(INT64_MIN, digits, status));
+        verifySource(75808.0, digits);
+        assertSuccess("75808", status);
+    }
+        
+}
+
+void NumberFormat2Test::TestIntInitVisibleDigits() {
+    VisibleDigits digits;
+    {
+        UErrorCode status = U_ZERO_ERROR;
+        FixedPrecision precision;
+        verifyVisibleDigits(
+                "13",
+                FALSE,
+                precision.initVisibleDigits((int64_t) 13LL, digits, status));
+        assertSuccess("13", status);
+    }
+    {
+        UErrorCode status = U_ZERO_ERROR;
+        FixedPrecision precision;
+        verifyVisibleDigits(
+                "17",
+                TRUE,
+                precision.initVisibleDigits((int64_t) -17LL, digits, status));
+        assertSuccess("-17", status);
+    }
+    {
+        UErrorCode status = U_ZERO_ERROR;
+        FixedPrecision precision;
+        verifyVisibleDigits(
+                "9223372036854775808",
+                TRUE,
+                precision.initVisibleDigits(INT64_MIN, digits, status));
+        assertSuccess("-9223372036854775808", status);
+    }
+    {
+        UErrorCode status = U_ZERO_ERROR;
+        FixedPrecision precision;
+        verifyVisibleDigits(
+                "9223372036854775807",
+                FALSE,
+                precision.initVisibleDigits(INT64_MAX, digits, status));
+        assertSuccess("9223372036854775807", status);
+    }
+    {
+        UErrorCode status = U_ZERO_ERROR;
+        FixedPrecision precision;
+        verifyVisibleDigits(
+                "31536000",
+                TRUE,
+                precision.initVisibleDigits((int64_t) -31536000LL, digits, status));
+        assertSuccess("-31536000", status);
+    }
+    {
+        UErrorCode status = U_ZERO_ERROR;
+        FixedPrecision precision;
+        verifyVisibleDigits(
+                "0",
+                FALSE,
+                precision.initVisibleDigits((int64_t) 0LL, digits, status));
+        assertSuccess("0", status);
+    }
+    {
+        UErrorCode status = U_ZERO_ERROR;
+        FixedPrecision precision;
+        precision.fMin.setIntDigitCount(4);
+        precision.fMin.setFracDigitCount(2);
+        verifyVisibleDigits(
+                "0000.00",
+                FALSE,
+                precision.initVisibleDigits((int64_t) 0LL, digits, status));
+        assertSuccess("0", status);
+    }
+    {
+        UErrorCode status = U_ZERO_ERROR;
+        FixedPrecision precision;
+        precision.fMin.setIntDigitCount(4);
+        precision.fMin.setFracDigitCount(2);
+        verifyVisibleDigits(
+                "0057.00",
+                FALSE,
+                precision.initVisibleDigits((int64_t) 57LL, digits, status));
+        assertSuccess("57", status);
+    }
+    {
+        UErrorCode status = U_ZERO_ERROR;
+        FixedPrecision precision;
+        precision.fMin.setIntDigitCount(4);
+        precision.fMin.setFracDigitCount(2);
+        verifyVisibleDigits(
+                "0057.00",
+                TRUE,
+                precision.initVisibleDigits((int64_t) -57LL, digits, status));
+        assertSuccess("-57", status);
+    }
+    {
+        UErrorCode status = U_ZERO_ERROR;
+        FixedPrecision precision;
+        precision.fMax.setIntDigitCount(2);
+        precision.fMin.setFracDigitCount(1);
+        verifyVisibleDigits(
+                "35.0",
+                FALSE,
+                precision.initVisibleDigits((int64_t) 235LL, digits, status));
+        assertSuccess("235", status);
+    }
+    {
+        UErrorCode status = U_ZERO_ERROR;
+        FixedPrecision precision;
+        precision.fMax.setIntDigitCount(2);
+        precision.fMin.setFracDigitCount(1);
+        precision.fFailIfOverMax = TRUE;
+        precision.initVisibleDigits((int64_t) 239LL, digits, status);
+        if (status != U_ILLEGAL_ARGUMENT_ERROR) {
+            errln("239: Expected U_ILLEGAL_ARGUMENT_ERROR");
+        }
+    }
+    {
+        UErrorCode status = U_ZERO_ERROR;
+        FixedPrecision precision;
+        precision.fSignificant.setMin(5);
+        verifyVisibleDigits(
+                "153.00",
+                FALSE,
+                precision.initVisibleDigits((int64_t) 153LL, digits, status));
+        assertSuccess("153", status);
+    }
+    {
+        UErrorCode status = U_ZERO_ERROR;
+        FixedPrecision precision;
+        precision.fSignificant.setMax(2);
+        precision.fExactOnly = TRUE;
+        precision.initVisibleDigits((int64_t) 154LL, digits, status);
+        if (status != U_FORMAT_INEXACT_ERROR) {
+            errln("154: Expected U_FORMAT_INEXACT_ERROR");
+        }
+    }
+    {
+        UErrorCode status = U_ZERO_ERROR;
+        FixedPrecision precision;
+        precision.fSignificant.setMax(5);
+        verifyVisibleDigits(
+                "150",
+                FALSE,
+                precision.initVisibleDigits((int64_t) 150LL, digits, status));
+        assertSuccess("150", status);
+    }
+}
+
+void NumberFormat2Test::TestIntInitVisibleDigitsToDigitList() {
+    VisibleDigits digits;
+    {
+        UErrorCode status = U_ZERO_ERROR;
+        FixedPrecision precision;
+        precision.fRoundingIncrement.set(7.3);
+        verifyVisibleDigits(
+                "29.2",
+                TRUE,
+                precision.initVisibleDigits((int64_t) -30LL, digits, status));
+        assertSuccess("-29.2", status);
+    }
+    {
+        UErrorCode status = U_ZERO_ERROR;
+        FixedPrecision precision;
+        precision.fRoundingIncrement.set(7.3);
+        precision.fRoundingMode = DecimalFormat::kRoundFloor;
+        verifyVisibleDigits(
+                "36.5",
+                TRUE,
+                precision.initVisibleDigits((int64_t) -30LL, digits, status));
+        assertSuccess("-36.5", status);
+    }
+    {
+        UErrorCode status = U_ZERO_ERROR;
+        FixedPrecision precision;
+        precision.fSignificant.setMax(3);
+        precision.fRoundingMode = DecimalFormat::kRoundCeiling;
+        verifyVisibleDigits(
+                "1390",
+                FALSE,
+                precision.initVisibleDigits((int64_t) 1381LL, digits, status));
+        assertSuccess("1390", status);
+    }
+    {
+        UErrorCode status = U_ZERO_ERROR;
+        FixedPrecision precision;
+        precision.fSignificant.setMax(1);
+        precision.fRoundingMode = DecimalFormat::kRoundFloor;
+        verifyVisibleDigits(
+                "2000",
+                TRUE,
+                precision.initVisibleDigits((int64_t) -1381LL, digits, status));
+        assertSuccess("-2000", status);
+    }
+}
+
+void NumberFormat2Test::TestDoubleInitVisibleDigits() {
+    VisibleDigits digits;
+    {
+        UErrorCode status = U_ZERO_ERROR;
+        FixedPrecision precision;
+        verifyVisibleDigits(
+                "2.05",
+                FALSE,
+                precision.initVisibleDigits(2.05, digits, status));
+        assertSuccess("2.05", status);
+    }
+    {
+        UErrorCode status = U_ZERO_ERROR;
+        FixedPrecision precision;
+        verifyVisibleDigits(
+                "3547",
+                FALSE,
+                precision.initVisibleDigits(3547.0, digits, status));
+        assertSuccess("3547", status);
+    }
+    {
+        UErrorCode status = U_ZERO_ERROR;
+        FixedPrecision precision;
+        precision.fMax.setFracDigitCount(2);
+        precision.fMax.setIntDigitCount(1);
+        precision.fFailIfOverMax = TRUE;
+        precision.fExactOnly = TRUE;
+        verifyVisibleDigits(
+                "2.05",
+                TRUE,
+                precision.initVisibleDigits(-2.05, digits, status));
+        assertSuccess("-2.05", status);
+    }
+    {
+        UErrorCode status = U_ZERO_ERROR;
+        FixedPrecision precision;
+        precision.fMax.setFracDigitCount(1);
+        precision.fMax.setIntDigitCount(1);
+        precision.fFailIfOverMax = TRUE;
+        precision.fExactOnly = TRUE;
+        precision.initVisibleDigits(-2.05, digits, status);
+        if (status != U_FORMAT_INEXACT_ERROR) {
+            errln("6245.3: Expected U_FORMAT_INEXACT_ERROR");
+        }
+    }
+    {
+        UErrorCode status = U_ZERO_ERROR;
+        FixedPrecision precision;
+        precision.fMax.setFracDigitCount(2);
+        precision.fMax.setIntDigitCount(0);
+        precision.fFailIfOverMax = TRUE;
+        precision.fExactOnly = TRUE;
+        precision.initVisibleDigits(-2.05, digits, status);
+        if (status != U_ILLEGAL_ARGUMENT_ERROR) {
+            errln("-2.05: Expected U_ILLEGAL_ARGUMENT_ERROR");
+        }
+    }
+    {
+        UErrorCode status = U_ZERO_ERROR;
+        FixedPrecision precision;
+        precision.fMin.setIntDigitCount(5);
+        precision.fMin.setFracDigitCount(2);
+        precision.fExactOnly = TRUE;
+        verifyVisibleDigits(
+                "06245.30",
+                FALSE,
+                precision.initVisibleDigits(6245.3, digits, status));
+        assertSuccess("06245.30", status);
+    }
+    {
+        UErrorCode status = U_ZERO_ERROR;
+        FixedPrecision precision;
+        precision.fSignificant.setMax(5);
+        precision.fExactOnly = TRUE;
+        verifyVisibleDigits(
+                "6245.3",
+                FALSE,
+                precision.initVisibleDigits(6245.3, digits, status));
+        assertSuccess("6245.3", status);
+    }
+    {
+        UErrorCode status = U_ZERO_ERROR;
+        FixedPrecision precision;
+        precision.fSignificant.setMax(4);
+        precision.fExactOnly = TRUE;
+        precision.initVisibleDigits(6245.3, digits, status);
+        if (status != U_FORMAT_INEXACT_ERROR) {
+            errln("6245.3: Expected U_FORMAT_INEXACT_ERROR");
+        }
+    }
+    {
+        UErrorCode status = U_ZERO_ERROR;
+        FixedPrecision precision;
+        precision.fMax.setIntDigitCount(3);
+        precision.fMin.setFracDigitCount(2);
+        verifyVisibleDigits(
+                "384.90",
+                FALSE,
+                precision.initVisibleDigits(2384.9, digits, status));
+        assertSuccess("380.00", status);
+    }
+    {
+        UErrorCode status = U_ZERO_ERROR;
+        FixedPrecision precision;
+        precision.fMax.setIntDigitCount(3);
+        precision.fMin.setFracDigitCount(2);
+        precision.fFailIfOverMax = TRUE;
+        precision.initVisibleDigits(2384.9, digits, status);
+        if (status != U_ILLEGAL_ARGUMENT_ERROR) {
+            errln("2384.9: Expected U_ILLEGAL_ARGUMENT_ERROR");
+        }
+    }
+}
+
+void NumberFormat2Test::TestDoubleInitVisibleDigitsToDigitList() {
+    VisibleDigits digits;
+    {
+        UErrorCode status = U_ZERO_ERROR;
+        FixedPrecision precision;
+        // 2.01 produces round off error when multiplied by powers of
+        // 10 forcing the use of DigitList.
+        verifyVisibleDigits(
+                "2.01",
+                TRUE,
+                precision.initVisibleDigits(-2.01, digits, status));
+        assertSuccess("-2.01", status);
+    }
+    {
+        UErrorCode status = U_ZERO_ERROR;
+        FixedPrecision precision;
+        precision.fSignificant.setMax(3);
+        precision.fMin.setFracDigitCount(2);
+        verifyVisibleDigits(
+                "2380.00",
+                FALSE,
+                precision.initVisibleDigits(2385.0, digits, status));
+        assertSuccess("2380.00", status);
+    }
+    {
+        UErrorCode status = U_ZERO_ERROR;
+        FixedPrecision precision;
+        precision.fMax.setFracDigitCount(2);
+        verifyVisibleDigits(
+                "45.83",
+                TRUE,
+                precision.initVisibleDigits(-45.8251, digits, status));
+        assertSuccess("45.83", status);
+    }
+}
+
+void NumberFormat2Test::TestDigitListInitVisibleDigits() {
+    VisibleDigits digits;
+    DigitList dlist;
+    {
+        UErrorCode status = U_ZERO_ERROR;
+        FixedPrecision precision;
+        precision.fMax.setIntDigitCount(3);
+        precision.fMin.setFracDigitCount(2);
+        precision.fFailIfOverMax = TRUE;
+        dlist.set(2384.9);
+        precision.initVisibleDigits(dlist, digits, status);
+        if (status != U_ILLEGAL_ARGUMENT_ERROR) {
+            errln("2384.9: Expected U_ILLEGAL_ARGUMENT_ERROR");
+        }
+    }
+    {
+        UErrorCode status = U_ZERO_ERROR;
+        FixedPrecision precision;
+        precision.fSignificant.setMax(4);
+        precision.fExactOnly = TRUE;
+        dlist.set(6245.3);
+        precision.initVisibleDigits(dlist, digits, status);
+        if (status != U_FORMAT_INEXACT_ERROR) {
+            errln("6245.3: Expected U_FORMAT_INEXACT_ERROR");
+        }
+    }
+}
+
+void NumberFormat2Test::TestSpecialInitVisibleDigits() {
+    VisibleDigits digits;
+    {
+        UErrorCode status = U_ZERO_ERROR;
+        FixedPrecision precision;
+        precision.fSignificant.setMax(3);
+        precision.fMin.setFracDigitCount(2);
+        precision.initVisibleDigits(-uprv_getInfinity(), digits, status);
+        assertFalse("", digits.isNaN());
+        assertTrue("", digits.isInfinite());
+        assertTrue("", digits.isNegative());
+        assertSuccess("-Inf", status);
+    }
+    {
+        UErrorCode status = U_ZERO_ERROR;
+        FixedPrecision precision;
+        precision.initVisibleDigits(uprv_getInfinity(), digits, status);
+        assertFalse("", digits.isNaN());
+        assertTrue("", digits.isInfinite());
+        assertFalse("", digits.isNegative());
+        assertSuccess("Inf", status);
+    }
+    {
+        UErrorCode status = U_ZERO_ERROR;
+        FixedPrecision precision;
+        precision.initVisibleDigits(uprv_getNaN(), digits, status);
+        assertTrue("", digits.isNaN());
+        assertSuccess("Inf", status);
+    }
+}
+
+void NumberFormat2Test::TestVisibleDigitsWithExponent() {
+    VisibleDigitsWithExponent digits;
+    {
+        UErrorCode status = U_ZERO_ERROR;
+        ScientificPrecision precision;
+        precision.initVisibleDigitsWithExponent(389.256, digits, status);
+        verifyVisibleDigitsWithExponent(
+                "3.89256E2", FALSE, digits);
+        assertSuccess("3.89256E2", status);
+    }
+    {
+        UErrorCode status = U_ZERO_ERROR;
+        ScientificPrecision precision;
+        precision.initVisibleDigitsWithExponent(-389.256, digits, status);
+        verifyVisibleDigitsWithExponent(
+                "3.89256E2", TRUE, digits);
+        assertSuccess("-3.89256E2", status);
+    }
+    {
+        UErrorCode status = U_ZERO_ERROR;
+        ScientificPrecision precision;
+        precision.fMinExponentDigits = 3;
+        precision.fMantissa.fMin.setIntDigitCount(1);
+        precision.fMantissa.fMax.setIntDigitCount(3);
+        precision.initVisibleDigitsWithExponent(12345.67, digits, status);
+        verifyVisibleDigitsWithExponent(
+                "12.34567E003", FALSE, digits);
+        assertSuccess("12.34567E003", status);
+    }
+    {
+        UErrorCode status = U_ZERO_ERROR;
+        ScientificPrecision precision;
+        precision.fMantissa.fRoundingIncrement.set(0.073);
+        precision.fMantissa.fMin.setIntDigitCount(2);
+        precision.fMantissa.fMax.setIntDigitCount(2);
+        precision.initVisibleDigitsWithExponent(999.74, digits, status);
+        verifyVisibleDigitsWithExponent(
+                "10.001E2", FALSE, digits);
+        assertSuccess("10.001E2", status);
+    }
+}
+
+void NumberFormat2Test::TestDigitAffixesAndPadding() {
+    UErrorCode status = U_ZERO_ERROR;
+    DecimalFormatSymbols symbols("en", status);
+    if (!assertSuccess("", status)) {
+        return;
+    }
+    DigitFormatter formatter(symbols);
+    DigitGrouping grouping;
+    grouping.fGrouping = 3;
+    FixedPrecision precision;
+    DigitFormatterOptions options;
+    options.fAlwaysShowDecimal = TRUE;
+    ValueFormatter vf;
+    vf.prepareFixedDecimalFormatting(
+            formatter,
+            grouping,
+            precision,
+            options);
+    DigitAffixesAndPadding aap;
+    aap.fPositivePrefix.append("(+", UNUM_SIGN_FIELD);
+    aap.fPositiveSuffix.append("+)", UNUM_SIGN_FIELD);
+    aap.fNegativePrefix.append("(-", UNUM_SIGN_FIELD);
+    aap.fNegativeSuffix.append("-)", UNUM_SIGN_FIELD);
+    aap.fWidth = 10;
+    aap.fPadPosition = DigitAffixesAndPadding::kPadBeforePrefix;
+    {
+        NumberFormat2Test_Attributes expectedAttributes[] = {
+            {UNUM_SIGN_FIELD, 4, 6},
+            {UNUM_INTEGER_FIELD, 6, 7},
+            {UNUM_DECIMAL_SEPARATOR_FIELD, 7, 8},
+            {UNUM_SIGN_FIELD, 8, 10},
+            {0, -1, 0}};
+        verifyAffixesAndPaddingInt32(
+                "****(+3.+)",
+                aap,
+                3,
+                vf,
+                NULL,
+                expectedAttributes);
+    }
+    aap.fPadPosition = DigitAffixesAndPadding::kPadAfterPrefix;
+    {
+        NumberFormat2Test_Attributes expectedAttributes[] = {
+            {UNUM_SIGN_FIELD, 0, 2},
+            {UNUM_INTEGER_FIELD, 6, 7},
+            {UNUM_DECIMAL_SEPARATOR_FIELD, 7, 8},
+            {UNUM_SIGN_FIELD, 8, 10},
+            {0, -1, 0}};
+        verifyAffixesAndPaddingInt32(
+                "(+****3.+)",
+                aap,
+                3,
+                vf,
+                NULL,
+                expectedAttributes);
+    }
+    aap.fPadPosition = DigitAffixesAndPadding::kPadBeforeSuffix;
+    {
+        NumberFormat2Test_Attributes expectedAttributes[] = {
+            {UNUM_SIGN_FIELD, 0, 2},
+            {UNUM_INTEGER_FIELD, 2, 3},
+            {UNUM_DECIMAL_SEPARATOR_FIELD, 3, 4},
+            {UNUM_SIGN_FIELD, 8, 10},
+            {0, -1, 0}};
+        verifyAffixesAndPaddingInt32(
+                "(+3.****+)",
+                aap,
+                3,
+                vf,
+                NULL,
+                expectedAttributes);
+    }
+    aap.fPadPosition = DigitAffixesAndPadding::kPadAfterSuffix;
+    {
+        NumberFormat2Test_Attributes expectedAttributes[] = {
+            {UNUM_SIGN_FIELD, 0, 2},
+            {UNUM_INTEGER_FIELD, 2, 3},
+            {UNUM_DECIMAL_SEPARATOR_FIELD, 3, 4},
+            {UNUM_SIGN_FIELD, 4, 6},
+            {0, -1, 0}};
+        verifyAffixesAndPaddingInt32(
+                "(+3.+)****",
+                aap,
+                3,
+                vf,
+                NULL,
+                expectedAttributes);
+    }
+    aap.fPadPosition = DigitAffixesAndPadding::kPadAfterSuffix;
+    {
+        DigitList digits;
+        digits.set(-1234.5);
+        NumberFormat2Test_Attributes expectedAttributes[] = {
+            {UNUM_SIGN_FIELD, 0, 2},
+            {UNUM_GROUPING_SEPARATOR_FIELD, 3, 4},
+            {UNUM_INTEGER_FIELD, 2, 7},
+            {UNUM_DECIMAL_SEPARATOR_FIELD, 7, 8},
+            {UNUM_FRACTION_FIELD, 8, 9},
+            {UNUM_SIGN_FIELD, 9, 11},
+            {0, -1, 0}};
+        verifyAffixesAndPadding(
+                "(-1,234.5-)",
+                aap,
+                digits,
+                vf,
+                NULL,
+                expectedAttributes);
+    }
+    assertFalse("", aap.needsPluralRules());
+
+    aap.fWidth = 0;
+    aap.fPositivePrefix.remove();
+    aap.fPositiveSuffix.remove();
+    aap.fNegativePrefix.remove();
+    aap.fNegativeSuffix.remove();
+    
+    // Set up for plural currencies.
+    aap.fNegativePrefix.append("-", UNUM_SIGN_FIELD);
+    {
+        PluralAffix part;
+        part.setVariant("one", " Dollar", status);
+        part.setVariant("other", " Dollars", status);
+        aap.fPositiveSuffix.append(part, UNUM_CURRENCY_FIELD, status);
+    }
+    aap.fNegativeSuffix = aap.fPositiveSuffix;
+    
+    LocalPointer<PluralRules> rules(PluralRules::forLocale("en", status));
+    if (!assertSuccess("", status)) {
+        return;
+    }
+
+    // Exercise the fastrack path
+    {
+        options.fAlwaysShowDecimal = FALSE;
+        NumberFormat2Test_Attributes expectedAttributes[] = {
+            {UNUM_SIGN_FIELD, 0, 1},
+            {UNUM_INTEGER_FIELD, 1, 3},
+            {UNUM_CURRENCY_FIELD, 3, 11},
+            {0, -1, 0}};
+        verifyAffixesAndPaddingInt32(
+                "-45 Dollars",
+                aap,
+                -45,
+                vf,
+                NULL,
+                expectedAttributes);
+        options.fAlwaysShowDecimal = TRUE;
+    }
+    
+    // Now test plurals
+    assertTrue("", aap.needsPluralRules());
+    {
+        NumberFormat2Test_Attributes expectedAttributes[] = {
+            {UNUM_INTEGER_FIELD, 0, 1},
+            {UNUM_DECIMAL_SEPARATOR_FIELD, 1, 2},
+            {UNUM_CURRENCY_FIELD, 2, 9},
+            {0, -1, 0}};
+        verifyAffixesAndPaddingInt32(
+                "1. Dollar",
+                aap,
+                1,
+                vf,
+                rules.getAlias(),
+                expectedAttributes);
+    }
+    {
+        NumberFormat2Test_Attributes expectedAttributes[] = {
+            {UNUM_SIGN_FIELD, 0, 1},
+            {UNUM_INTEGER_FIELD, 1, 2},
+            {UNUM_DECIMAL_SEPARATOR_FIELD, 2, 3},
+            {UNUM_CURRENCY_FIELD, 3, 10},
+            {0, -1, 0}};
+        verifyAffixesAndPaddingInt32(
+                "-1. Dollar",
+                aap,
+                -1,
+                vf,
+                rules.getAlias(),
+                expectedAttributes);
+    }
+    precision.fMin.setFracDigitCount(2);
+    {
+        NumberFormat2Test_Attributes expectedAttributes[] = {
+            {UNUM_INTEGER_FIELD, 0, 1},
+            {UNUM_DECIMAL_SEPARATOR_FIELD, 1, 2},
+            {UNUM_FRACTION_FIELD, 2, 4},
+            {UNUM_CURRENCY_FIELD, 4, 12},
+            {0, -1, 0}};
+        verifyAffixesAndPaddingInt32(
+                "1.00 Dollars",
+                aap,
+                1,
+                vf,
+                rules.getAlias(),
+                expectedAttributes);
+    }
+}
+
+void NumberFormat2Test::TestPluralsAndRounding() {
+    UErrorCode status = U_ZERO_ERROR;
+    DecimalFormatSymbols symbols("en", status);
+    if (!assertSuccess("", status)) {
+        return;
+    }
+    DigitFormatter formatter(symbols);
+    DigitGrouping grouping;
+    FixedPrecision precision;
+    precision.fSignificant.setMax(3);
+    DigitFormatterOptions options;
+    ValueFormatter vf;
+    vf.prepareFixedDecimalFormatting(
+            formatter,
+            grouping,
+            precision,
+            options);
+    DigitList digits;
+    DigitAffixesAndPadding aap;
+    // Set up for plural currencies.
+    aap.fNegativePrefix.append("-", UNUM_SIGN_FIELD);
+    {
+        PluralAffix part;
+        part.setVariant("one", " Dollar", status);
+        part.setVariant("other", " Dollars", status);
+        aap.fPositiveSuffix.append(part, UNUM_CURRENCY_FIELD, status);
+    }
+    aap.fNegativeSuffix = aap.fPositiveSuffix;
+    aap.fWidth = 14;
+    LocalPointer<PluralRules> rules(PluralRules::forLocale("en", status));
+    if (!assertSuccess("", status)) {
+        return;
+    }
+    {
+        digits.set(0.999);
+        verifyAffixesAndPadding(
+                "*0.999 Dollars",
+                aap,
+                digits,
+                vf,
+                rules.getAlias(),
+                NULL);
+    }
+    {
+        digits.set(0.9996);
+        verifyAffixesAndPadding(
+                "******1 Dollar",
+                aap,
+                digits,
+                vf,
+                rules.getAlias(),
+                NULL);
+    }
+    {
+        digits.set(1.004);
+        verifyAffixesAndPadding(
+                "******1 Dollar",
+                aap,
+                digits,
+                vf,
+                rules.getAlias(),
+                NULL);
+    }
+    precision.fSignificant.setMin(2);
+    {
+        digits.set(0.9996);
+        verifyAffixesAndPadding(
+                "***1.0 Dollars",
+                aap,
+                digits,
+                vf,
+                rules.getAlias(),
+                NULL);
+    }
+    {
+        digits.set(1.004);
+        verifyAffixesAndPadding(
+                "***1.0 Dollars",
+                aap,
+                digits,
+                vf,
+                rules.getAlias(),
+                NULL);
+    }
+    precision.fSignificant.setMin(0);
+    {
+        digits.set(-79.214);
+        verifyAffixesAndPadding(
+                "*-79.2 Dollars",
+                aap,
+                digits,
+                vf,
+                rules.getAlias(),
+                NULL);
+    }
+    // No more sig digits just max fractions
+    precision.fSignificant.setMax(0); 
+    precision.fMax.setFracDigitCount(4);
+    {
+        digits.set(79.213562);
+        verifyAffixesAndPadding(
+                "79.2136 Dollars",
+                aap,
+                digits,
+                vf,
+                rules.getAlias(),
+                NULL);
+    }
+
+}
+
+
+void NumberFormat2Test::TestPluralsAndRoundingScientific() {
+    UErrorCode status = U_ZERO_ERROR;
+    DecimalFormatSymbols symbols("en", status);
+    if (!assertSuccess("", status)) {
+        return;
+    }
+    DigitFormatter formatter(symbols);
+    ScientificPrecision precision;
+    precision.fMantissa.fSignificant.setMax(4);
+    SciFormatterOptions options;
+    ValueFormatter vf;
+    vf.prepareScientificFormatting(
+            formatter,
+            precision,
+            options);
+    DigitList digits;
+    DigitAffixesAndPadding aap;
+    aap.fNegativePrefix.append("-", UNUM_SIGN_FIELD);
+    {
+        PluralAffix part;
+        part.setVariant("one", " Meter", status);
+        part.setVariant("other", " Meters", status);
+        aap.fPositiveSuffix.append(part, UNUM_FIELD_COUNT, status);
+    }
+    aap.fNegativeSuffix = aap.fPositiveSuffix;
+    LocalPointer<PluralRules> rules(PluralRules::forLocale("en", status));
+    if (!assertSuccess("", status)) {
+        return;
+    }
+    {
+        digits.set(0.99996);
+        NumberFormat2Test_Attributes expectedAttributes[] = {
+            {UNUM_INTEGER_FIELD, 0, 1},
+            {UNUM_EXPONENT_SYMBOL_FIELD, 1, 2},
+            {UNUM_EXPONENT_FIELD, 2, 3},
+            {0, -1, 0}};
+        verifyAffixesAndPadding(
+                "1E0 Meters",
+                aap,
+                digits,
+                vf,
+                rules.getAlias(),
+                expectedAttributes);
+    }
+    options.fMantissa.fAlwaysShowDecimal = TRUE;
+    {
+        digits.set(0.99996);
+        NumberFormat2Test_Attributes expectedAttributes[] = {
+            {UNUM_INTEGER_FIELD, 0, 1},
+            {UNUM_DECIMAL_SEPARATOR_FIELD, 1, 2},
+            {UNUM_EXPONENT_SYMBOL_FIELD, 2, 3},
+            {UNUM_EXPONENT_FIELD, 3, 4},
+            {0, -1, 0}};
+        verifyAffixesAndPadding(
+                "1.E0 Meters",
+                aap,
+                digits,
+                vf,
+                rules.getAlias(),
+                expectedAttributes);
+    }
+    {
+        digits.set(-299792458);
+        NumberFormat2Test_Attributes expectedAttributes[] = {
+            {UNUM_SIGN_FIELD, 0, 1},
+            {UNUM_INTEGER_FIELD, 1, 2},
+            {UNUM_DECIMAL_SEPARATOR_FIELD, 2, 3},
+            {UNUM_FRACTION_FIELD, 3, 6},
+            {UNUM_EXPONENT_SYMBOL_FIELD, 6, 7},
+            {UNUM_EXPONENT_FIELD, 7, 8},
+            {0, -1, 0}};
+        verifyAffixesAndPadding(
+                "-2.998E8 Meters",
+                aap,
+                digits,
+                vf,
+                rules.getAlias(),
+                expectedAttributes);
+    }
+    precision.fMantissa.fSignificant.setMin(4);
+    options.fExponent.fAlwaysShowSign = TRUE;
+    precision.fMinExponentDigits = 3;
+    {
+        digits.set(3);
+        NumberFormat2Test_Attributes expectedAttributes[] = {
+            {UNUM_INTEGER_FIELD, 0, 1},
+            {UNUM_DECIMAL_SEPARATOR_FIELD, 1, 2},
+            {UNUM_FRACTION_FIELD, 2, 5},
+            {UNUM_EXPONENT_SYMBOL_FIELD, 5, 6},
+            {UNUM_EXPONENT_SIGN_FIELD, 6, 7},
+            {UNUM_EXPONENT_FIELD, 7, 10},
+            {0, -1, 0}};
+        verifyAffixesAndPadding(
+                "3.000E+000 Meters",
+                aap,
+                digits,
+                vf,
+                rules.getAlias(),
+                expectedAttributes);
+    }
+    precision.fMantissa.fMax.setIntDigitCount(3);
+    {
+        digits.set(0.00025001);
+        NumberFormat2Test_Attributes expectedAttributes[] = {
+            {UNUM_INTEGER_FIELD, 0, 3},
+            {UNUM_DECIMAL_SEPARATOR_FIELD, 3, 4},
+            {UNUM_FRACTION_FIELD, 4, 5},
+            {UNUM_EXPONENT_SYMBOL_FIELD, 5, 6},
+            {UNUM_EXPONENT_SIGN_FIELD, 6, 7},
+            {UNUM_EXPONENT_FIELD, 7, 10},
+            {0, -1, 0}};
+        verifyAffixesAndPadding(
+                "250.0E-006 Meters",
+                aap,
+                digits,
+                vf,
+                rules.getAlias(),
+                expectedAttributes);
+    }
+    {
+        digits.set(0.0000025001);
+        NumberFormat2Test_Attributes expectedAttributes[] = {
+            {UNUM_INTEGER_FIELD, 0, 1},
+            {UNUM_DECIMAL_SEPARATOR_FIELD, 1, 2},
+            {UNUM_FRACTION_FIELD, 2, 5},
+            {UNUM_EXPONENT_SYMBOL_FIELD, 5, 6},
+            {UNUM_EXPONENT_SIGN_FIELD, 6, 7},
+            {UNUM_EXPONENT_FIELD, 7, 10},
+            {0, -1, 0}};
+        verifyAffixesAndPadding(
+                "2.500E-006 Meters",
+                aap,
+                digits,
+                vf,
+                rules.getAlias(),
+                expectedAttributes);
+    }
+    precision.fMantissa.fMax.setFracDigitCount(1);
+    {
+        digits.set(0.0000025499);
+        NumberFormat2Test_Attributes expectedAttributes[] = {
+            {UNUM_INTEGER_FIELD, 0, 1},
+            {UNUM_DECIMAL_SEPARATOR_FIELD, 1, 2},
+            {UNUM_FRACTION_FIELD, 2, 3},
+            {UNUM_EXPONENT_SYMBOL_FIELD, 3, 4},
+            {UNUM_EXPONENT_SIGN_FIELD, 4, 5},
+            {UNUM_EXPONENT_FIELD, 5, 8},
+            {0, -1, 0}};
+        verifyAffixesAndPadding(
+                "2.5E-006 Meters",
+                aap,
+                digits,
+                vf,
+                rules.getAlias(),
+                expectedAttributes);
+    }
+    precision.fMantissa.fMax.setIntDigitCount(1);
+    precision.fMantissa.fMax.setFracDigitCount(2);
+    {
+        digits.set(299792458);
+        verifyAffixesAndPadding(
+                "3.00E+008 Meters",
+                aap,
+                digits,
+                vf,
+                rules.getAlias(),
+                NULL);
+    }
+    // clear significant digits
+    precision.fMantissa.fSignificant.setMin(0);
+    precision.fMantissa.fSignificant.setMax(0);
+
+    // set int and fraction digits
+    precision.fMantissa.fMin.setFracDigitCount(2);
+    precision.fMantissa.fMax.setFracDigitCount(4);
+    precision.fMantissa.fMin.setIntDigitCount(2);
+    precision.fMantissa.fMax.setIntDigitCount(3);
+    {
+        digits.set(-0.0000025300001);
+        verifyAffixesAndPadding(
+                "-253.00E-008 Meters",
+                aap,
+                digits,
+                vf,
+                rules.getAlias(),
+                NULL);
+    }
+    {
+        digits.set(-0.0000025300006);
+        verifyAffixesAndPadding(
+                "-253.0001E-008 Meters",
+                aap,
+                digits,
+                vf,
+                rules.getAlias(),
+                NULL);
+    }
+    {
+        digits.set(-0.000025300006);
+        verifyAffixesAndPadding(
+                "-25.30E-006 Meters",
+                aap,
+                digits,
+                vf,
+                rules.getAlias(),
+                NULL);
+    }
+}
+
+
+void NumberFormat2Test::TestRoundingIncrement() {
+    UErrorCode status = U_ZERO_ERROR;
+    DecimalFormatSymbols symbols("en", status);
+    if (U_FAILURE(status)) {
+        dataerrln("Error creating DecimalFormatSymbols - %s", u_errorName(status));
+        return;
+    }
+    DigitFormatter formatter(symbols);
+    ScientificPrecision precision;
+    SciFormatterOptions options;
+    precision.fMantissa.fRoundingIncrement.set(0.25);
+    precision.fMantissa.fSignificant.setMax(4);
+    DigitGrouping grouping;
+    ValueFormatter vf;
+
+    // fixed
+    vf.prepareFixedDecimalFormatting(
+            formatter,
+            grouping,
+            precision.fMantissa,
+            options.fMantissa);
+    DigitList digits;
+    DigitAffixesAndPadding aap;
+    aap.fNegativePrefix.append("-", UNUM_SIGN_FIELD);
+    {
+        digits.set(3.7);
+        verifyAffixesAndPadding(
+                "3.75",
+                aap,
+                digits,
+                vf,
+                NULL, NULL);
+    }
+    {
+        digits.set(-7.4);
+        verifyAffixesAndPadding(
+                "-7.5",
+                aap,
+                digits,
+                vf,
+                NULL, NULL);
+    }
+    {
+        digits.set(99.8);
+        verifyAffixesAndPadding(
+                "99.75",
+                aap,
+                digits,
+                vf,
+                NULL, NULL);
+    }
+    precision.fMantissa.fMin.setFracDigitCount(2);
+    {
+        digits.set(99.1);
+        verifyAffixesAndPadding(
+                "99.00",
+                aap,
+                digits,
+                vf,
+                NULL, NULL);
+    }
+    {
+        digits.set(-639.65);
+        verifyAffixesAndPadding(
+                "-639.80",
+                aap,
+                digits,
+                vf,
+                NULL, NULL);
+    }
+
+    precision.fMantissa.fMin.setIntDigitCount(2);
+    // Scientific notation
+    vf.prepareScientificFormatting(
+            formatter,
+            precision,
+            options);
+    {
+        digits.set(-6396.5);
+        verifyAffixesAndPadding(
+                "-64.00E2",
+                aap,
+                digits,
+                vf,
+                NULL, NULL);
+    }
+    {
+        digits.set(-0.00092374);
+        verifyAffixesAndPadding(
+                "-92.25E-5",
+                aap,
+                digits,
+                vf,
+                NULL, NULL);
+    }
+    precision.fMantissa.fMax.setIntDigitCount(3);
+    {
+        digits.set(-0.00092374);
+        verifyAffixesAndPadding(
+                "-923.80E-6",
+                aap,
+                digits,
+                vf,
+                NULL, NULL);
+    }
+}
+
+void NumberFormat2Test::TestToPatternScientific11648() {
+/*
+    UErrorCode status = U_ZERO_ERROR;
+    Locale en("en");
+    DecimalFormat2 fmt(en, "0.00", status);
+    fmt.setScientificNotation(TRUE);
+    UnicodeString pattern;
+    // Fails, produces "0.00E"
+    assertEquals("", "0.00E0", fmt.toPattern(pattern));
+    DecimalFormat fmt2(pattern, status);
+    // Fails, bad pattern.
+    assertSuccess("", status);
+*/
+}
+
+void NumberFormat2Test::verifyAffixesAndPadding(
+        const UnicodeString &expected,
+        const DigitAffixesAndPadding &aaf,
+        DigitList &digits,
+        const ValueFormatter &vf,
+        const PluralRules *optPluralRules,
+        const NumberFormat2Test_Attributes *expectedAttributes) {
+    UnicodeString appendTo;
+    NumberFormat2Test_FieldPositionHandler handler;
+    UErrorCode status = U_ZERO_ERROR;
+    assertEquals(
+            "",
+            expected,
+            aaf.format(
+                    digits,
+                    vf,
+                    handler,
+                    optPluralRules,
+                    appendTo,
+                    status));
+    if (!assertSuccess("", status)) {
+        return;
+    }
+    if (expectedAttributes != NULL) {
+        verifyAttributes(expectedAttributes, handler.attributes);
+    }
+}
+
+void NumberFormat2Test::verifyAffixesAndPaddingInt32(
+        const UnicodeString &expected,
+        const DigitAffixesAndPadding &aaf,
+        int32_t value,
+        const ValueFormatter &vf,
+        const PluralRules *optPluralRules,
+        const NumberFormat2Test_Attributes *expectedAttributes) {
+    UnicodeString appendTo;
+    NumberFormat2Test_FieldPositionHandler handler;
+    UErrorCode status = U_ZERO_ERROR;
+    assertEquals(
+            "",
+            expected,
+            aaf.formatInt32(
+                    value,
+                    vf,
+                    handler,
+                    optPluralRules,
+                    appendTo,
+                    status));
+    if (!assertSuccess("", status)) {
+        return;
+    }
+    if (expectedAttributes != NULL) {
+        verifyAttributes(expectedAttributes, handler.attributes);
+    }
+    DigitList digits;
+    digits.set(value);
+    verifyAffixesAndPadding(
+            expected, aaf, digits, vf, optPluralRules, expectedAttributes);
+}
+
+void NumberFormat2Test::verifyAffix(
+        const UnicodeString &expected,
+        const DigitAffix &affix,
+        const NumberFormat2Test_Attributes *expectedAttributes) {
+    UnicodeString appendTo;
+    NumberFormat2Test_FieldPositionHandler handler;
+    assertEquals(
+            "",
+            expected.unescape(),
+            affix.format(handler, appendTo));
+    if (expectedAttributes != NULL) {
+        verifyAttributes(expectedAttributes, handler.attributes);
+    }
+}
+
+// Right now only works for positive values.
+void NumberFormat2Test::verifyDigitList(
+        const UnicodeString &expected,
+        const DigitList &digits) {
+    DigitFormatter formatter;
+    DigitGrouping grouping;
+    VisibleDigits visibleDigits;
+    FixedPrecision precision;
+    precision.fMin.setIntDigitCount(0);
+    DigitFormatterOptions options;
+    UErrorCode status = U_ZERO_ERROR;
+    DigitList dlCopy(digits);
+    precision.initVisibleDigits(
+            dlCopy, visibleDigits, status);
+    if (!assertSuccess("", status)) {
+        return;
+    }
+    verifyDigitFormatter(
+            expected,
+            formatter,
+            visibleDigits,
+            grouping,
+            options,
+            NULL);
+}
+
+void NumberFormat2Test::verifyVisibleDigits(
+        const UnicodeString &expected,
+        UBool bNegative,
+        const VisibleDigits &digits) {
+    DigitFormatter formatter;
+    DigitGrouping grouping;
+    DigitFormatterOptions options;
+    verifyDigitFormatter(
+            expected,
+            formatter,
+            digits,
+            grouping,
+            options,
+            NULL);
+    if (digits.isNegative() != bNegative) {
+        errln(expected + ": Wrong sign.");
+    }
+    if (digits.isNaN() || digits.isInfinite()) {
+        errln(expected + ": Require real value.");
+    }
+}
+
+void NumberFormat2Test::verifyVisibleDigitsWithExponent(
+        const UnicodeString &expected,
+        UBool bNegative,
+        const VisibleDigitsWithExponent &digits) {
+    DigitFormatter formatter;
+    SciFormatterOptions options;
+    verifySciFormatter(
+            expected,
+            formatter,
+            digits,
+            options,
+            NULL);
+    if (digits.isNegative() != bNegative) {
+        errln(expected + ": Wrong sign.");
+    }
+    if (digits.isNaN() || digits.isInfinite()) {
+        errln(expected + ": Require real value.");
+    }
+}
+
+void NumberFormat2Test::verifySciFormatter(
+        const UnicodeString &expected,
+        const DigitFormatter &formatter,
+        const VisibleDigitsWithExponent &digits,
+        const SciFormatterOptions &options,
+        const NumberFormat2Test_Attributes *expectedAttributes) {
+    assertEquals(
+            "",
+            expected.countChar32(),
+            formatter.countChar32(digits, options));
+    UnicodeString appendTo;
+    NumberFormat2Test_FieldPositionHandler handler;
+    assertEquals(
+            "",
+            expected,
+            formatter.format(
+                    digits,
+                    options,
+                    handler,
+                    appendTo));
+    if (expectedAttributes != NULL) {
+        verifyAttributes(expectedAttributes, handler.attributes);
+    }
+}
+
+void NumberFormat2Test::verifyPositiveIntDigitFormatter(
+        const UnicodeString &expected,
+        const DigitFormatter &formatter,
+        int32_t value,
+        int32_t minDigits,
+        int32_t maxDigits,
+        const NumberFormat2Test_Attributes *expectedAttributes) {
+    IntDigitCountRange range(minDigits, maxDigits);
+    UnicodeString appendTo;
+    NumberFormat2Test_FieldPositionHandler handler;
+    assertEquals(
+            "",
+            expected,
+            formatter.formatPositiveInt32(
+                    value,
+                    range,
+                    handler,
+                    appendTo));
+    if (expectedAttributes != NULL) {
+        verifyAttributes(expectedAttributes, handler.attributes);
+    }
+}
+
+void NumberFormat2Test::verifyDigitFormatter(
+        const UnicodeString &expected,
+        const DigitFormatter &formatter,
+        const VisibleDigits &digits,
+        const DigitGrouping &grouping,
+        const DigitFormatterOptions &options,
+        const NumberFormat2Test_Attributes *expectedAttributes) {
+    assertEquals(
+            "",
+            expected.countChar32(),
+            formatter.countChar32(digits, grouping, options));
+    UnicodeString appendTo;
+    NumberFormat2Test_FieldPositionHandler handler;
+    assertEquals(
+            "",
+            expected,
+            formatter.format(
+                    digits,
+                    grouping,
+                    options,
+                    handler,
+                    appendTo));
+    if (expectedAttributes != NULL) {
+        verifyAttributes(expectedAttributes, handler.attributes);
+    }
+}
+
+void NumberFormat2Test::verifySmallIntFormatter(
+        const UnicodeString &expected,
+        int32_t positiveValue,
+        int32_t minDigits,
+        int32_t maxDigits) {
+    IntDigitCountRange range(minDigits, maxDigits);
+    if (!SmallIntFormatter::canFormat(positiveValue, range)) {
+        UnicodeString actual;
+        assertEquals("", expected, actual);
+        return;
+    }
+    UnicodeString actual;
+    assertEquals("", expected, SmallIntFormatter::format(positiveValue, range, actual));
+}
+
+void NumberFormat2Test::verifyAttributes(
+        const NumberFormat2Test_Attributes *expected,
+        const NumberFormat2Test_Attributes *actual) {
+    int32_t idx = 0;
+    while (expected[idx].spos != -1 && actual[idx].spos != -1) {
+        assertEquals("id", expected[idx].id, actual[idx].id);
+        assertEquals("spos", expected[idx].spos, actual[idx].spos);
+        assertEquals("epos", expected[idx].epos, actual[idx].epos);
+        ++idx;
+    }
+    assertEquals(
+            "expected and actual not same length",
+            expected[idx].spos,
+            actual[idx].spos);
+}
+
+void NumberFormat2Test::verifyIntValue(
+        int64_t expected, const VisibleDigits &digits) {
+    double unusedSource;
+    int64_t intValue;
+    int64_t unusedF;
+    int64_t unusedT;
+    int32_t unusedV;
+    UBool unusedHasIntValue;
+    digits.getFixedDecimal(
+            unusedSource, intValue, unusedF,
+            unusedT, unusedV, unusedHasIntValue);
+    assertEquals("", expected, intValue);
+}
+
+void NumberFormat2Test::verifySource(
+        double expected, const VisibleDigits &digits) {
+    double source;
+    int64_t unusedIntValue;
+    int64_t unusedF;
+    int64_t unusedT;
+    int32_t unusedV;
+    UBool unusedHasIntValue;
+    digits.getFixedDecimal(
+            source, unusedIntValue, unusedF,
+            unusedT, unusedV, unusedHasIntValue);
+    if (expected != source) {
+        errln("Expected %f, got %f instead", expected, source);
+    }
+}
+
+extern IntlTest *createNumberFormat2Test() {
+    return new NumberFormat2Test();
+}
+
+#endif /* !UCONFIG_NO_FORMATTING */