Integer.valueOf 阿拉伯数字工作正常但 Float.valueOf 相同的数字给出 NumberFormatException
Integer.valueOf Arabic number works fine but Float.valueOf the same number gives NumberFormatException
使用阿拉伯数字 Integer.valueOf("۱")
returns 整数 1 但 Float.valueOf("۱")
或 Float.parseFloat("۱")
抛出 NumberFormatException
而如果你使用英文则不会抛出任何异常数字 Float.valueOf("1")
,它是 java 中的错误还是有一些解释?
如何解析这样的数字?
我在 android 环境中工作;
Float.valueOf(String)
的规范说:
Leading and trailing whitespace characters in s are ignored.
Whitespace is removed as if by the String.trim() method; that is, both
ASCII space and control characters are removed. The rest of s should
constitute a FloatValue as described by the lexical syntax rules:
FloatValue:
Signopt NaN
Signopt Infinity
Signopt FloatingPointLiteral
Signopt HexFloatingPointLiteral
SignedInteger
...
最接近你所拥有的词法规则是SignedInteger
, which consists of an optional sign, and then 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)
refer to Integer.parseInt(String)
,它简单地说:
The characters in the string must all be decimal digits, except that the first character may be an ASCII minus sign
"Decimal digits" 比 0-9 宽;什么都在DECIMAL_DIGIT_NUMBER
can be used, for example (不要脸的外挂)。
更准确地说,.
所以,这符合规定;您是否认为这是正确的规范是另一回事。
好像是Float.parseFloat()
does not support Eastern-Arabic numbers. Alternatively, you can use NumberFormat
class:
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() 获取字符串中每个数字的值。
Research/Explanation
我用 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
的数字值。
使用阿拉伯数字 Integer.valueOf("۱")
returns 整数 1 但 Float.valueOf("۱")
或 Float.parseFloat("۱")
抛出 NumberFormatException
而如果你使用英文则不会抛出任何异常数字 Float.valueOf("1")
,它是 java 中的错误还是有一些解释?
如何解析这样的数字?
我在 android 环境中工作;
Float.valueOf(String)
的规范说:
Leading and trailing whitespace characters in s are ignored. Whitespace is removed as if by the String.trim() method; that is, both ASCII space and control characters are removed. The rest of s should constitute a FloatValue as described by the lexical syntax rules:
FloatValue: Signopt NaN Signopt Infinity Signopt FloatingPointLiteral Signopt HexFloatingPointLiteral SignedInteger ...
最接近你所拥有的词法规则是SignedInteger
, which consists of an optional sign, and then 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)
refer to Integer.parseInt(String)
,它简单地说:
The characters in the string must all be decimal digits, except that the first character may be an ASCII minus sign
"Decimal digits" 比 0-9 宽;什么都在DECIMAL_DIGIT_NUMBER
can be used, for example
更准确地说,.
所以,这符合规定;您是否认为这是正确的规范是另一回事。
好像是Float.parseFloat()
does not support Eastern-Arabic numbers. Alternatively, you can use NumberFormat
class:
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() 获取字符串中每个数字的值。
Research/Explanation
我用 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
的数字值。