"[\\ '\\u00A0\\u066C\\u2000-\\u200A\\u2018\\u2019\\u202F\\u205F\\u3000\\uFF07]")
.freeze();
+ // For parse return value calculation.
+ private static final BigDecimal MIN_LONG_AS_BIG_DECIMAL = new BigDecimal(Long.MIN_VALUE);
+ private static final BigDecimal MAX_LONG_AS_BIG_DECIMAL = new BigDecimal(Long.MAX_VALUE);
+
private enum SeparatorType {
COMMA_LIKE,
PERIOD_LIKE,
result = result.stripTrailingZeros();
if (forceBigDecimal || result.scale() > 0) {
return result;
- } else if (-result.scale() + result.precision() <= 18) {
+ } else if (result.compareTo(MIN_LONG_AS_BIG_DECIMAL) >= 0
+ && result.compareTo(MAX_LONG_AS_BIG_DECIMAL) <= 0) {
return result.longValueExact();
} else {
return result.toBigIntegerExact();
}
/**
- * Whether to force {@link #parse} to always return a BigDecimal. By default, {@link #parse} will
- * return different data types as follows:
+ * Whether to make {@link #parse} prefer returning a {@link com.ibm.icu.math.BigDecimal} when
+ * possible. For strings corresponding to return values of Infinity, -Infinity, NaN, and -0.0, a
+ * Double will be returned even if ParseBigDecimal is enabled.
*
- * <ol>
- * <li>If the number is an integer (has no fraction part), return a Long if possible, or else a
- * BigInteger.
- * <li>Otherwise, return a BigDecimal.
- * </ol>
- *
- * If this setting is enabled, a BigDecimal will be returned even if the number is an integer.
- *
- * @param value true to cause {@link #parse} to always return a BigDecimal; false to let {@link
- * #parse} return different data types.
+ * @param value true to cause {@link #parse} to prefer BigDecimal; false to let {@link #parse}
+ * return additional data types like Long or BigInteger.
* @category Parsing
* @stable ICU 3.6
*/
/**
* Returns a Long if possible (e.g., within the range [Long.MIN_VALUE,
- * Long.MAX_VALUE] and with no decimals), otherwise a Double.
- * If IntegerOnly is set, will stop at a decimal
+ * Long.MAX_VALUE] and with no decimals); otherwise, returns another type,
+ * such as a BigDecimal, BigInteger, or Double. The return type is not
+ * guaranteed other than for the Long case.
+ *
+ * <p>If IntegerOnly is set, will stop at a decimal
* point (or equivalent; e.g., for rational numbers "1 2/3", will stop
* after the 1).
- * Does not throw an exception; if no object can be parsed, index is
+ *
+ * <p>Does not throw an exception; if no object can be parsed, index is
* unchanged!
+ *
* @see #isParseIntegerOnly
+ * @see DecimalFormat#setParseBigDecimal
* @see java.text.Format#parseObject(String, ParsePosition)
* @stable ICU 2.0
*/
@Test
public void TestParseReturnType() {
- String[] defaultNonBigDecimals = {
- "123", // Long
- "123.0", // Long
- "0.0", // Long
- "12345678901234567890" // BigInteger
+ String[] defaultLong = {
+ "123",
+ "123.0",
+ "0.0",
+ "-9223372036854775808", // Min Long
+ "9223372036854775807" // Max Long
+ };
+
+ String[] defaultNonLong = {
+ "12345678901234567890",
+ "9223372036854775808",
+ "-9223372036854775809"
};
String[] doubles = {
}
// isParseBigDecimal() is false
- for (int i = 0; i < defaultNonBigDecimals.length; i++) {
+ for (int i = 0; i < defaultLong.length; i++) {
+ try {
+ Number n = nf.parse(defaultLong[i]);
+ if (!(n instanceof Long)) {
+ errln("FAIL: parse does not return Long instance");
+ }
+ } catch (ParseException e) {
+ errln("parse of '" + defaultLong[i] + "' threw exception: " + e);
+ }
+ }
+ for (int i = 0; i < defaultNonLong.length; i++) {
try {
- Number n = nf.parse(defaultNonBigDecimals[i]);
- if (n instanceof BigDecimal) {
- errln("FAIL: parse returns BigDecimal instance");
+ Number n = nf.parse(defaultNonLong[i]);
+ // For backwards compatibility with this test, BigDecimal is checked.
+ if ((n instanceof Long) || (n instanceof BigDecimal)) {
+ errln("FAIL: parse returned a Long or a BigDecimal");
}
} catch (ParseException e) {
- errln("parse of '" + defaultNonBigDecimals[i] + "' threw exception: " + e);
+ errln("parse of '" + defaultNonLong[i] + "' threw exception: " + e);
}
}
// parse results for doubls must be always Double
}
// isParseBigDecimal() is true
- for (int i = 0; i < defaultNonBigDecimals.length; i++) {
+ for (int i = 0; i < defaultLong.length + defaultNonLong.length; i++) {
+ String input = (i < defaultLong.length) ? defaultLong[i] : defaultNonLong[i - defaultLong.length];
try {
- Number n = nf.parse(defaultNonBigDecimals[i]);
+ Number n = nf.parse(input);
if (!(n instanceof BigDecimal)) {
errln("FAIL: parse does not return BigDecimal instance");
}
} catch (ParseException e) {
- errln("parse of '" + defaultNonBigDecimals[i] + "' threw exception: " + e);
+ errln("parse of '" + input + "' threw exception: " + e);
}
}
// parse results for doubls must be always Double