Integer.valueOf Arabic number工作正常,但Float.valueOf the Same nu



使用阿拉伯数字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-9Integer.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中的任何内容,例如"१२३"(无耻的插头(。

更准确地说,.


因此,这是按照规定行事;您是否认为这是一个正确的规范是另一回事。

最新更新