我想准确地解析一个整数,一个可能根据当前语言环境格式化的整数。如果我没有准确解析整数,我想知道它。所以我使用:
String string = "1111122222333334444455555";
Locale locale = Locale.getDefault();
NumberFormat numberFormat = NumberFormat.getIntegerInstance(locale);
numberFormat.setParseIntegerOnly();
Number number = numberFormat.parse(string);
显然,"1111122222333334444455555"
代表一个很大的数字,比Long
可以处理的还要大。所以NumberFormat
给了我...Double
??
我想我本来希望收到一个BigInteger
而不是一个Double
,特别是因为我要求一个特定于整数的数字格式化器。但没关系;更大的问题是我得到的双倍值是1.1111222223333344E24
!这不等于1111122222333334444455555
!!
如果NumberFormat
给我一个解析的值,该值不等于存储在输入字符串中的值,我该如何检测?
换句话说:"我怎么知道我从NumberFormat
得到的Double
值是否与原始字符串中表示的整数值完全等同?
parse()
的javadocs声明,如果可能的话,它将返回一个Long,否则它将返回一个Double。 因此,只需检查返回值是否为 Long 即可。
"如果可能,则返回一个 Long(例如,在 [Long.MIN_VALUE, Long.MAX_VALUE] 范围内并且没有小数),否则返回 Double。
"我怎么知道我从 NumberFormat 返回的双精度值是否与原始字符串中表示的整数值完全等效?"
如果它返回 Double,则它不完全等同于您的整数值,因为 Double 无法准确表示该量级的值。 具体例子:
Number a = numberFormat.parse("-9223372036854775809"); // Integer.MIN_VALUE - 1
Number b = numberFormat.parse("-9223372036854775810"); // Integer.MIN_VALUE - 2
System.out.println((a.equals(b))); // prints "true"
Number c = numberFormat.parse("-9223372036854776800");
System.out.println((a.equals(c))); // prints "true"
对于你的问题 -
If NumberFormat gives me a parsed value that does not equal that stored in the input string, how do I detect that?
您可以使用
if(number.toString().equals(string))
//Parsed correctly
else
//Invalid parse
这可能不是解决方案,但值得注意。
public static void main(String[] args) {
String string = "1111122222333334444455555";
Locale locale = Locale.getDefault();
NumberFormat numberFormat = NumberFormat.getIntegerInstance(locale);
numberFormat.setParseIntegerOnly(true);
Number number = numberFormat.parse(string);
BigDecimal b = new BigDecimal(number.toString());
System.out.println(b.toBigInteger());
}
此代码的输出为: 1111122222333334400000000
如您所见,这不等于实际字符串中的数字,因此它们可能是溢出的。