U_DEFAULT_KEYWORD_MISSING, /**< Missing DEFAULT rule in plural rules */
U_DECIMAL_NUMBER_SYNTAX_ERROR, /**< Decimal number syntax error */
U_FORMAT_INEXACT_ERROR, /**< Cannot format a number exactly and rounding mode is ROUND_UNNECESSARY @stable ICU 4.8 */
+ U_NUMBER_ARG_OUTOFBOUNDS_ERROR, /**< The argument to a NumberFormatter helper method was out of bounds; the bounds are usually 0 to 999. @draft ICU 61 */
#ifndef U_HIDE_DEPRECATED_API
/**
* One more than the highest normal formatting API error code.
"U_UNDEFINED_KEYWORD",
"U_DEFAULT_KEYWORD_MISSING",
"U_DECIMAL_NUMBER_SYNTAX_ERROR",
- "U_FORMAT_INEXACT_ERROR"
+ "U_FORMAT_INEXACT_ERROR",
+ "U_NUMBER_ARG_OUTOFBOUNDS_ERROR"
};
static const char * const
using namespace icu::number;
using namespace icu::number::impl;
-IntegerWidth::IntegerWidth(int8_t minInt, int8_t maxInt) {
+IntegerWidth::IntegerWidth(digits_t minInt, digits_t maxInt) {
fUnion.minMaxInt.fMinInt = minInt;
fUnion.minMaxInt.fMaxInt = maxInt;
}
IntegerWidth IntegerWidth::zeroFillTo(int32_t minInt) {
if (minInt >= 0 && minInt <= kMaxIntFracSig) {
- return {static_cast<int8_t>(minInt), -1};
+ return {static_cast<digits_t>(minInt), -1};
} else {
- return {U_NUMBER_DIGIT_WIDTH_OUTOFBOUNDS_ERROR};
+ return {U_NUMBER_ARG_OUTOFBOUNDS_ERROR};
}
}
IntegerWidth IntegerWidth::truncateAt(int32_t maxInt) {
if (fHasError) { return *this; } // No-op on error
- if (maxInt >= 0 && maxInt <= kMaxIntFracSig) {
- return {fUnion.minMaxInt.fMinInt, static_cast<int8_t>(maxInt)};
+ digits_t minInt = fUnion.minMaxInt.fMinInt;
+ if (maxInt >= 0 && maxInt <= kMaxIntFracSig && minInt <= maxInt) {
+ return {minInt, static_cast<digits_t>(maxInt)};
+ } else if (maxInt == -1) {
+ return {minInt, -1};
} else {
- return {U_NUMBER_DIGIT_WIDTH_OUTOFBOUNDS_ERROR};
+ return {U_NUMBER_ARG_OUTOFBOUNDS_ERROR};
}
}
ScientificNotation
ScientificNotation::withMinExponentDigits(int32_t minExponentDigits) const {
- if (minExponentDigits >= 0 && minExponentDigits < kMaxIntFracSig) {
+ if (minExponentDigits >= 1 && minExponentDigits <= kMaxIntFracSig) {
ScientificSettings settings = fUnion.scientific;
- settings.fMinExponentDigits = (int8_t) minExponentDigits;
+ settings.fMinExponentDigits = static_cast<digits_t>(minExponentDigits);
NotationUnion union_ = {settings};
return {NTN_SCIENTIFIC, union_};
} else {
- return {U_NUMBER_DIGIT_WIDTH_OUTOFBOUNDS_ERROR};
+ return {U_NUMBER_ARG_OUTOFBOUNDS_ERROR};
}
}
if (targetWidth >= 0) {
return {cp, targetWidth, position};
} else {
- return {U_NUMBER_PADDING_WIDTH_OUTOFBOUNDS_ERROR};
+ return {U_NUMBER_ARG_OUTOFBOUNDS_ERROR};
}
}
if (minMaxFractionPlaces >= 0 && minMaxFractionPlaces <= kMaxIntFracSig) {
return constructFraction(minMaxFractionPlaces, minMaxFractionPlaces);
} else {
- return {U_NUMBER_DIGIT_WIDTH_OUTOFBOUNDS_ERROR};
+ return {U_NUMBER_ARG_OUTOFBOUNDS_ERROR};
}
}
if (minFractionPlaces >= 0 && minFractionPlaces <= kMaxIntFracSig) {
return constructFraction(minFractionPlaces, -1);
} else {
- return {U_NUMBER_DIGIT_WIDTH_OUTOFBOUNDS_ERROR};
+ return {U_NUMBER_ARG_OUTOFBOUNDS_ERROR};
}
}
if (maxFractionPlaces >= 0 && maxFractionPlaces <= kMaxIntFracSig) {
return constructFraction(0, maxFractionPlaces);
} else {
- return {U_NUMBER_DIGIT_WIDTH_OUTOFBOUNDS_ERROR};
+ return {U_NUMBER_ARG_OUTOFBOUNDS_ERROR};
}
}
minFractionPlaces <= maxFractionPlaces) {
return constructFraction(minFractionPlaces, maxFractionPlaces);
} else {
- return {U_NUMBER_DIGIT_WIDTH_OUTOFBOUNDS_ERROR};
+ return {U_NUMBER_ARG_OUTOFBOUNDS_ERROR};
}
}
Rounder Rounder::fixedDigits(int32_t minMaxSignificantDigits) {
- if (minMaxSignificantDigits >= 0 && minMaxSignificantDigits <= kMaxIntFracSig) {
+ if (minMaxSignificantDigits >= 1 && minMaxSignificantDigits <= kMaxIntFracSig) {
return constructSignificant(minMaxSignificantDigits, minMaxSignificantDigits);
} else {
- return {U_NUMBER_DIGIT_WIDTH_OUTOFBOUNDS_ERROR};
+ return {U_NUMBER_ARG_OUTOFBOUNDS_ERROR};
}
}
Rounder Rounder::minDigits(int32_t minSignificantDigits) {
- if (minSignificantDigits >= 0 && minSignificantDigits <= kMaxIntFracSig) {
+ if (minSignificantDigits >= 1 && minSignificantDigits <= kMaxIntFracSig) {
return constructSignificant(minSignificantDigits, -1);
} else {
- return {U_NUMBER_DIGIT_WIDTH_OUTOFBOUNDS_ERROR};
+ return {U_NUMBER_ARG_OUTOFBOUNDS_ERROR};
}
}
Rounder Rounder::maxDigits(int32_t maxSignificantDigits) {
- if (maxSignificantDigits >= 0 && maxSignificantDigits <= kMaxIntFracSig) {
- return constructSignificant(0, maxSignificantDigits);
+ if (maxSignificantDigits >= 1 && maxSignificantDigits <= kMaxIntFracSig) {
+ return constructSignificant(1, maxSignificantDigits);
} else {
- return {U_NUMBER_DIGIT_WIDTH_OUTOFBOUNDS_ERROR};
+ return {U_NUMBER_ARG_OUTOFBOUNDS_ERROR};
}
}
Rounder Rounder::minMaxDigits(int32_t minSignificantDigits, int32_t maxSignificantDigits) {
- if (minSignificantDigits >= 0 && maxSignificantDigits <= kMaxIntFracSig &&
+ if (minSignificantDigits >= 1 && maxSignificantDigits <= kMaxIntFracSig &&
minSignificantDigits <= maxSignificantDigits) {
return constructSignificant(minSignificantDigits, maxSignificantDigits);
} else {
- return {U_NUMBER_DIGIT_WIDTH_OUTOFBOUNDS_ERROR};
+ return {U_NUMBER_ARG_OUTOFBOUNDS_ERROR};
}
}
if (roundingIncrement > 0.0) {
return constructIncrement(roundingIncrement, 0);
} else {
- return {U_NUMBER_DIGIT_WIDTH_OUTOFBOUNDS_ERROR};
+ return {U_NUMBER_ARG_OUTOFBOUNDS_ERROR};
}
}
Rounder FractionRounder::withMinDigits(int32_t minSignificantDigits) const {
if (fType == RND_ERROR) { return *this; } // no-op in error state
- if (minSignificantDigits >= 0 && minSignificantDigits <= kMaxIntFracSig) {
+ if (minSignificantDigits >= 1 && minSignificantDigits <= kMaxIntFracSig) {
return constructFractionSignificant(*this, minSignificantDigits, -1);
} else {
- return {U_NUMBER_DIGIT_WIDTH_OUTOFBOUNDS_ERROR};
+ return {U_NUMBER_ARG_OUTOFBOUNDS_ERROR};
}
}
Rounder FractionRounder::withMaxDigits(int32_t maxSignificantDigits) const {
if (fType == RND_ERROR) { return *this; } // no-op in error state
- if (maxSignificantDigits >= 0 && maxSignificantDigits <= kMaxIntFracSig) {
+ if (maxSignificantDigits >= 1 && maxSignificantDigits <= kMaxIntFracSig) {
return constructFractionSignificant(*this, -1, maxSignificantDigits);
} else {
- return {U_NUMBER_DIGIT_WIDTH_OUTOFBOUNDS_ERROR};
+ return {U_NUMBER_ARG_OUTOFBOUNDS_ERROR};
}
}
if (minFrac >= 0 && minFrac <= kMaxIntFracSig) {
return constructIncrement(fUnion.increment.fIncrement, minFrac);
} else {
- return {U_NUMBER_DIGIT_WIDTH_OUTOFBOUNDS_ERROR};
+ return {U_NUMBER_ARG_OUTOFBOUNDS_ERROR};
}
}
FractionRounder Rounder::constructFraction(int32_t minFrac, int32_t maxFrac) {
FractionSignificantSettings settings;
- settings.fMinFrac = static_cast<int8_t> (minFrac);
- settings.fMaxFrac = static_cast<int8_t> (maxFrac);
+ settings.fMinFrac = static_cast<digits_t>(minFrac);
+ settings.fMaxFrac = static_cast<digits_t>(maxFrac);
settings.fMinSig = -1;
settings.fMaxSig = -1;
RounderUnion union_;
FractionSignificantSettings settings;
settings.fMinFrac = -1;
settings.fMaxFrac = -1;
- settings.fMinSig = static_cast<int8_t>(minSig);
- settings.fMaxSig = static_cast<int8_t>(maxSig);
+ settings.fMinSig = static_cast<digits_t>(minSig);
+ settings.fMaxSig = static_cast<digits_t>(maxSig);
RounderUnion union_;
union_.fracSig = settings;
return {RND_SIGNIFICANT, union_, kDefaultMode};
Rounder
Rounder::constructFractionSignificant(const FractionRounder &base, int32_t minSig, int32_t maxSig) {
FractionSignificantSettings settings = base.fUnion.fracSig;
- settings.fMinSig = static_cast<int8_t>(minSig);
- settings.fMaxSig = static_cast<int8_t>(maxSig);
+ settings.fMinSig = static_cast<digits_t>(minSig);
+ settings.fMaxSig = static_cast<digits_t>(maxSig);
RounderUnion union_;
union_.fracSig = settings;
return {RND_FRACTION_SIGNIFICANT, union_, kDefaultMode};
IncrementRounder Rounder::constructIncrement(double increment, int32_t minFrac) {
IncrementSettings settings;
settings.fIncrement = increment;
- settings.fMinFrac = minFrac;
+ settings.fMinFrac = static_cast<digits_t>(minFrac);
RounderUnion union_;
union_.increment = settings;
return {RND_INCREMENT, union_, kDefaultMode};
typedef UNumberCompactStyle CompactStyle;
// ICU4J Equivalent: RoundingUtils.MAX_INT_FRAC_SIG
-static constexpr int32_t kMaxIntFracSig = 100;
+static constexpr int32_t kMaxIntFracSig = 999;
// ICU4J Equivalent: RoundingUtils.DEFAULT_ROUNDING_MODE
static constexpr RoundingMode kDefaultMode = RoundingMode::UNUM_FOUND_HALFEVEN;
// ICU4J Equivalent: NumberFormatterImpl.DEFAULT_CURRENCY
static constexpr char16_t kDefaultCurrency[] = u"XXX";
-// FIXME: New error codes:
-static constexpr UErrorCode U_NUMBER_DIGIT_WIDTH_OUTOFBOUNDS_ERROR = U_ILLEGAL_ARGUMENT_ERROR;
-static constexpr UErrorCode U_NUMBER_PADDING_WIDTH_OUTOFBOUNDS_ERROR = U_ILLEGAL_ARGUMENT_ERROR;
-
// Forward declarations:
class Modifier;
namespace impl {
+/**
+ * Datatype for minimum/maximum fraction digits. Must be able to hold kMaxIntFracSig.
+ *
+ * @internal
+ */
+typedef int16_t digits_t;
+
+/**
+ * Use a default threshold of 3. This means that the third time .format() is called, the data structures get built
+ * using the "safe" code path. The first two calls to .format() will trigger the unsafe code path.
+ *
+ * @internal
+ */
+static constexpr int32_t DEFAULT_THRESHOLD = 3;
+
// Forward declarations:
class Padder;
struct MacroProps;
struct ScientificSettings {
int8_t fEngineeringInterval;
bool fRequireMinInt;
- int8_t fMinExponentDigits;
+ impl::digits_t fMinExponentDigits;
UNumberSignDisplay fExponentSignDisplay;
} scientific;
union RounderUnion {
struct FractionSignificantSettings {
// For RND_FRACTION, RND_SIGNIFICANT, and RND_FRACTION_SIGNIFICANT
- int8_t fMinFrac;
- int8_t fMaxFrac;
- int8_t fMinSig;
- int8_t fMaxSig;
+ impl::digits_t fMinFrac;
+ impl::digits_t fMaxFrac;
+ impl::digits_t fMinSig;
+ impl::digits_t fMaxSig;
} fracSig;
struct IncrementSettings {
double fIncrement;
- int32_t fMinFrac;
+ impl::digits_t fMinFrac;
} increment; // For RND_INCREMENT
UCurrencyUsage currencyUsage; // For RND_CURRENCY
UErrorCode errorCode; // For RND_ERROR
* For example, with maxInt=3, the number 1234 will get printed as "234".
*
* @param maxInt
- * The maximum number of places before the decimal separator.
+ * The maximum number of places before the decimal separator. maxInt == -1 means no
+ * truncation.
* @return An IntegerWidth for passing to the NumberFormatter integerWidth() setter.
* @draft ICU 60
* @see NumberFormatter
private:
union {
struct {
- int8_t fMinInt;
- int8_t fMaxInt;
+ impl::digits_t fMinInt;
+ impl::digits_t fMaxInt;
} minMaxInt;
UErrorCode errorCode;
} fUnion;
bool fHasError = false;
- IntegerWidth(int8_t minInt, int8_t maxInt);
+ IntegerWidth(impl::digits_t minInt, impl::digits_t maxInt);
IntegerWidth(UErrorCode errorCode) { // NOLINT
fUnion.errorCode = errorCode;
namespace impl {
-/**
- * Use a default threshold of 3. This means that the third time .format() is called, the data structures get built
- * using the "safe" code path. The first two calls to .format() will trigger the unsafe code path.
- *
- * @internal
- */
-static constexpr int32_t DEFAULT_THRESHOLD = 3;
-
/** @internal */
class U_I18N_API SymbolsWrapper : public UMemory {
public:
return TRUE;
}
+
+UBool IntlTest::assertEquals(const char* message,
+ UErrorCode expected,
+ UErrorCode actual) {
+ if (expected != actual) {
+ errln((UnicodeString)"FAIL: " + message + "; got " +
+ u_errorName(actual) +
+ "; expected " + u_errorName(expected));
+ return FALSE;
+ }
+#ifdef VERBOSE_ASSERTIONS
+ else {
+ logln((UnicodeString)"Ok: " + message + "; got " + u_errorName(actual));
+ }
+#endif
+ return TRUE;
+}
+
+
#if !UCONFIG_NO_FORMATTING
UBool IntlTest::assertEquals(const char* message,
const Formattable& expected,
int64_t actual) {
return assertEquals(extractToAssertBuf(message), expected, actual);
}
+UBool IntlTest::assertEquals(const UnicodeString& message,
+ double expected,
+ double actual) {
+ return assertEquals(extractToAssertBuf(message), expected, actual);
+}
+UBool IntlTest::assertEquals(const UnicodeString& message,
+ UErrorCode expected,
+ UErrorCode actual) {
+ return assertEquals(extractToAssertBuf(message), expected, actual);
+}
#if !UCONFIG_NO_FORMATTING
UBool IntlTest::assertEquals(const UnicodeString& message,
UBool assertSuccess(const char* message, UErrorCode ec, UBool possibleDataError=FALSE, const char *file=NULL, int line=0);
UBool assertEquals(const char* message, const UnicodeString& expected,
const UnicodeString& actual, UBool possibleDataError=FALSE);
- UBool assertEquals(const char* message, const char* expected,
- const char* actual);
- UBool assertEquals(const char* message, UBool expected,
- UBool actual);
+ UBool assertEquals(const char* message, const char* expected, const char* actual);
+ UBool assertEquals(const char* message, UBool expected, UBool actual);
UBool assertEquals(const char* message, int32_t expected, int32_t actual);
UBool assertEquals(const char* message, int64_t expected, int64_t actual);
UBool assertEquals(const char* message, double expected, double actual);
+ UBool assertEquals(const char* message, UErrorCode expected, UErrorCode actual);
#if !UCONFIG_NO_FORMATTING
UBool assertEquals(const char* message, const Formattable& expected,
const Formattable& actual, UBool possibleDataError=FALSE);
UBool assertSuccess(const UnicodeString& message, UErrorCode ec);
UBool assertEquals(const UnicodeString& message, const UnicodeString& expected,
const UnicodeString& actual, UBool possibleDataError=FALSE);
- UBool assertEquals(const UnicodeString& message, const char* expected,
- const char* actual);
+ UBool assertEquals(const UnicodeString& message, const char* expected, const char* actual);
UBool assertEquals(const UnicodeString& message, UBool expected, UBool actual);
UBool assertEquals(const UnicodeString& message, int32_t expected, int32_t actual);
UBool assertEquals(const UnicodeString& message, int64_t expected, int64_t actual);
+ UBool assertEquals(const UnicodeString& message, double expected, double actual);
+ UBool assertEquals(const UnicodeString& message, UErrorCode expected, UErrorCode actual);
virtual void runIndexedTest( int32_t index, UBool exec, const char* &name, char* par = NULL ); // overide !
void locale();
void formatTypes();
void errors();
+ void validRanges();
void runIndexedTest(int32_t index, UBool exec, const char *&name, char *par = 0);
TESTCASE_AUTO(locale);
TESTCASE_AUTO(formatTypes);
TESTCASE_AUTO(errors);
+ TESTCASE_AUTO(validRanges);
TESTCASE_AUTO_END;
}
UErrorCode status2 = U_ZERO_ERROR;
FormattedNumber fn = lnf.formatInt(1, status1);
assertEquals(
- "Should fail with U_ILLEGAL_ARGUMENT_ERROR since rounder is not legal",
- U_ILLEGAL_ARGUMENT_ERROR,
- status1);
+ "Should fail since rounder is not legal",
+ (UBool) TRUE,
+ (UBool) U_FAILURE(status1));
FieldPosition fp;
fn.populateFieldPosition(fp, status2);
assertEquals(
- "Should fail with U_ILLEGAL_ARGUMENT_ERROR on terminal method",
- U_ILLEGAL_ARGUMENT_ERROR,
- status2);
+ "Should fail on terminal method",
+ (UBool) TRUE,
+ (UBool) U_FAILURE(status2));
}
{
UErrorCode status = U_ZERO_ERROR;
lnf.copyErrorTo(status);
assertEquals(
- "Should fail with U_ILLEGAL_ARGUMENT_ERROR since rounder is not legal",
- U_ILLEGAL_ARGUMENT_ERROR,
- status);
+ "Should fail since rounder is not legal",
+ (UBool) TRUE,
+ (UBool) U_FAILURE(status));
}
}
+void NumberFormatterApiTest::validRanges() {
+
+#define EXPECTED_MAX_INT_FRAC_SIG 999
+
+#define VALID_RANGE_ASSERT(status, method, lowerBound, argument) { \
+ UErrorCode expectedStatus = ((lowerBound <= argument) && (argument <= EXPECTED_MAX_INT_FRAC_SIG)) \
+ ? U_ZERO_ERROR \
+ : U_NUMBER_ARG_OUTOFBOUNDS_ERROR; \
+ assertEquals( \
+ UnicodeString(u"Incorrect status for " #method " on input ") \
+ + Int64ToUnicodeString(argument), \
+ expectedStatus, \
+ status); \
+}
+
+#define VALID_RANGE_ONEARG(setting, method, lowerBound) { \
+ for (int32_t argument = -2; argument <= EXPECTED_MAX_INT_FRAC_SIG + 2; argument++) { \
+ UErrorCode status = U_ZERO_ERROR; \
+ NumberFormatter::with().setting(method(argument)).copyErrorTo(status); \
+ VALID_RANGE_ASSERT(status, method, lowerBound, argument); \
+ } \
+}
+
+#define VALID_RANGE_TWOARGS(setting, method, lowerBound) { \
+ for (int32_t argument = -2; argument <= EXPECTED_MAX_INT_FRAC_SIG + 2; argument++) { \
+ UErrorCode status = U_ZERO_ERROR; \
+ /* Pass EXPECTED_MAX_INT_FRAC_SIG as the second argument so arg1 <= arg2 in expected cases */ \
+ NumberFormatter::with().setting(method(argument, EXPECTED_MAX_INT_FRAC_SIG)).copyErrorTo(status); \
+ VALID_RANGE_ASSERT(status, method, lowerBound, argument); \
+ status = U_ZERO_ERROR; \
+ /* Pass lowerBound as the first argument so arg1 <= arg2 in expected cases */ \
+ NumberFormatter::with().setting(method(lowerBound, argument)).copyErrorTo(status); \
+ VALID_RANGE_ASSERT(status, method, lowerBound, argument); \
+ /* Check that first argument must be less than or equal to second argument */ \
+ NumberFormatter::with().setting(method(argument, argument - 1)).copyErrorTo(status); \
+ assertEquals("Incorrect status for " #method " on max < min input", \
+ U_NUMBER_ARG_OUTOFBOUNDS_ERROR, \
+ status); \
+ } \
+}
+
+ VALID_RANGE_ONEARG(rounding, Rounder::fixedFraction, 0);
+ VALID_RANGE_ONEARG(rounding, Rounder::minFraction, 0);
+ VALID_RANGE_ONEARG(rounding, Rounder::maxFraction, 0);
+ VALID_RANGE_TWOARGS(rounding, Rounder::minMaxFraction, 0);
+ VALID_RANGE_ONEARG(rounding, Rounder::fixedDigits, 1);
+ VALID_RANGE_ONEARG(rounding, Rounder::minDigits, 1);
+ VALID_RANGE_ONEARG(rounding, Rounder::maxDigits, 1);
+ VALID_RANGE_TWOARGS(rounding, Rounder::minMaxDigits, 1);
+ VALID_RANGE_ONEARG(rounding, Rounder::fixedFraction(1).withMinDigits, 1);
+ VALID_RANGE_ONEARG(rounding, Rounder::fixedFraction(1).withMaxDigits, 1);
+ VALID_RANGE_ONEARG(notation, Notation::scientific().withMinExponentDigits, 1);
+ VALID_RANGE_ONEARG(integerWidth, IntegerWidth::zeroFillTo, 0);
+ VALID_RANGE_ONEARG(integerWidth, IntegerWidth::zeroFillTo(0).truncateAt, -1);
+}
+
void NumberFormatterApiTest::assertFormatDescending(const UnicodeString &message,
const UnlocalizedNumberFormatter &f,
* The maximum number of fraction places, integer numerals, or significant digits. TODO: This does
* not feel like the best home for this value.
*/
- public static final int MAX_INT_FRAC_SIG = 100;
+ public static final int MAX_INT_FRAC_SIG = 999;
/**
* Converts a rounding mode and metadata about the quantity being rounded to a boolean determining
Rounder.class.getDeclaredMethod("minMaxFraction", Integer.TYPE, Integer.TYPE),
Rounder.class.getDeclaredMethod("minMaxDigits", Integer.TYPE, Integer.TYPE), };
- final int EXPECTED_MAX_INT_FRAC_SIG = 100;
- final String expectedSubstring0 = "between 0 and 100 (inclusive)";
- final String expectedSubstring1 = "between 1 and 100 (inclusive)";
- final String expectedSubstringN1 = "between -1 and 100 (inclusive)";
+ final int EXPECTED_MAX_INT_FRAC_SIG = 999;
+ final String expectedSubstring0 = "between 0 and 999 (inclusive)";
+ final String expectedSubstring1 = "between 1 and 999 (inclusive)";
+ final String expectedSubstringN1 = "between -1 and 999 (inclusive)";
- // We require that the upper bounds all be 100 inclusive.
+ // We require that the upper bounds all be 999 inclusive.
// The lower bound may be either -1, 0, or 1.
Set<String> methodsWithLowerBound1 = new HashSet();
methodsWithLowerBound1.add("fixedDigits");
methodsWithLowerBound1.add("withMinDigits");
methodsWithLowerBound1.add("withMaxDigits");
methodsWithLowerBound1.add("withMinExponentDigits");
+ // Methods with lower bound 0:
+ // fixedFraction
+ // minFraction
+ // maxFraction
+ // minMaxFraction
+ // zeroFillTo
Set<String> methodsWithLowerBoundN1 = new HashSet();
methodsWithLowerBoundN1.add("truncateAt");