使用阿拉伯数字Integer.valueOf("۱")
返回整数 1,但Float.valueOf("۱")
或Float.parseFloat("۱")
抛出NumberFormatException
,而如果您使用英语数字Float.valueOf("1")
,它不会引发任何异常,这是 java 中的错误还是有一些解释?
如何解析这样的数字?
我在安卓环境中工作;
似乎Float.parseFloat()
不支持东方阿拉伯数字。或者,您可以使用NumberFormat
类:
Locale EASTERN_ARABIC_NUMBERS_LOCALE = new Locale.Builder()
.setLanguage("ar")
.setExtension('u', "nu-arab")
.build();
float f = NumberFormat.getInstance(EASTERN_ARABIC_NUMBERS_LOCALE)
.parse("۱٫۵")
.floatValue();
System.out.println(f);
输出:
1.5
答案
在Float.valueOf("۱")
中,没有检查不同的语言或字符,它只检查数字0-9
。Integer.valueOf
使用 Character.digit(( 获取字符串中每个数字的值。
研究/解释
我使用 Intellij 调试器调试了语句Float.valueOf("۱")
。如果您深入研究 FloatingDecimal.java,似乎此代码决定了哪个字符应计为数字:
digitLoop:
while (i < len) {
c = in.charAt(i);
if (c >= '1' && c <= '9') {
digits[nDigits++] = c;
nTrailZero = 0;
} else if (c == '0') {
digits[nDigits++] = c;
nTrailZero++;
} else if (c == '.') {
if (decSeen) {
// already saw one ., this is the 2nd.
throw new NumberFormatException("multiple points");
}
decPt = i;
if (signSeen) {
decPt -= 1;
}
decSeen = true;
} else {
break digitLoop;
}
i++;
}
如您所见,没有检查不同的语言,它只检查数字0-9
。
在逐步执行Integer.valueOf
,
public static int parseInt(String s, int radix)
以s = "۱"
和radix = 10
执行。
然后,parseInt 方法调用Character.digit('۱',10)
来获取1
的数字值。
参见字符数字((
Float.valueOf(String)
的规范说:
s 中的前导和尾随空格字符将被忽略。 空格被移除,就像通过 String.trim(( 方法一样;也就是说,两者兼而有之 删除 ASCII 空格和控制字符。其余的应该 构成一个由词法语法规则描述的浮点值:
FloatValue: Signopt NaN Signopt Infinity Signopt FloatingPointLiteral Signopt HexFloatingPointLiteral SignedInteger ...
最接近您拥有的规则是SignedInteger
,它由一个可选符号组成,然后是Digits
,只能0-9
。
Digits:
Digit
Digit [DigitsAndUnderscores] Digit
Digit:
0
NonZeroDigit
NonZeroDigit:
(one of)
1 2 3 4 5 6 7 8 9
另一方面,Integer.valueOf(String)
指的是Integer.parseInt(String)
,它只是说:
字符串中的字符必须全部为十进制数字,但第一个字符可以是 ASCII 减号
"十进制数字"比0-9宽;可以使用DECIMAL_DIGIT_NUMBER
中的任何内容,例如"१२३"(无耻的插头(。
更准确地说,.
因此,这是按照规定行事;您是否认为这是一个正确的规范是另一回事。