为什么 parseInt(8,3) == NaN 和 parseInt(16,3) == 1?
Why is it that parseInt(8,3) == NaN and parseInt(16,3) == 1?
我正在阅读 this 但我对 parseInt 中带有基数参数 章节
的内容感到困惑
为什么parseInt(8, 3)
→NaN
和parseInt(16, 3)
→1
?
AFAIK 8 和 16 不是基数 3,所以 parseInt(16, 3)
也应该 return NaN
这是人们经常犯的错误,即使他们知道了。 :-) 您看到这个的原因与 parseInt("1abc")
returns 1 相同:parseInt
在第一个无效字符处停止,returns 在该点处的任何内容。如果没有可解析的有效字符,则 returns NaN
.
parseInt(8, 3)
表示"parse "8"
in base 3"(注意它将数字8
转换为字符串;details in the spec)。但是在基数 3 中,个位数只是 0
、1
和 2
。这就像要求它以八进制解析 "9"
一样。由于 没有 个有效字符,您得到 NaN
.
parseInt(16, 3)
要求它在基数 3 中解析 "16"
。因为它可以解析 1
,所以它会解析,然后在 6
处停止,因为它无法解析它。所以它 returns 1
.
由于这个问题受到了很多关注并且可能在搜索结果中排名靠前,这里列出了 JavaScript 中将字符串转换为数字的选项,以及它们的各种特性和应用(摘自另一个答案我在这里的 SO):
parseInt(str[, radix])
- 将字符串的开头尽可能多地转换为一个完整(整数)数字,忽略末尾的额外字符。所以 parseInt("10x")
是 10
; x
被忽略。支持可选的基数(数字基数)参数,因此 parseInt("15", 16)
是 21
(十六进制的 15
)。如果没有基数,则假定为十进制,除非字符串以 0x
(或 0X
)开头,在这种情况下它会跳过这些并假定为十六进制。 (一些浏览器曾经将以 0
开头的字符串视为八进制;这种行为从未被指定,在 ES5 规范中是 specifically disallowed。) Returns NaN
如果找不到可解析的数字。
parseFloat(str)
- 与 parseInt
相似,但支持浮点数且仅支持小数。字符串上的额外字符再次被忽略,因此 parseFloat("10.5x")
是 10.5
(x
被忽略)。由于仅支持十进制,因此 parseFloat("0x15")
是 0
(因为解析在 x
处结束)。 Returns NaN
如果找不到可解析的数字。
一元 +
,例如+str
- (例如,隐式转换) 使用浮点数和 JavaScript 将 整个 字符串转换为数字标准数字表示法(仅数字和小数点 = 十进制;0x
前缀 = 十六进制;0o
前缀 = 八进制 [ES2015+];一些 实现扩展它以处理前导 0
作为八进制,但不是在严格模式下)。 +"10x"
是 NaN
因为 x
而不是 被忽略。 +"10"
是10
,+"10.5"
是10.5
,+"0x15"
是21
,+"0o10"
是8
[ES2015+] .有一个陷阱:+""
是 0
,而不是您可能期望的 NaN
。
Number(str)
- 完全像隐式转换(例如,像上面的一元 +
),但在某些实现上更慢。 (并不是说这很重要。)
出于同样的原因
>> parseInt('1foobar',3)
<- 1
在the doc中,parseInt
接受一个字符串。并且
If string is not a string, then it is converted to a string
因此16
、8
或'1foobar'
首先转换为字符串。
然后
If parseInt
encounters a character that is not a numeral in the specified radix, it ignores it and all succeeding characters
意味着它会尽可能地转换。 6
、8
、foobar
被忽略,只转换之前的内容。如果什么都没有,则返回NaN
。
/***** Radix 3: Allowed numbers are [0,1,2] ********/
parseInt(4, 3); // NaN - We can't represent 4 using radix 3 [allowed - 0,1,2]
parseInt(3, 3); // NaN - We can't represent 3 using radix 3 [allowed - 0,1,2]
parseInt(2, 3); // 2 - yes we can !
parseInt(8, 3); // NaN - We can't represent 8 using radix 3 [allowed - 0,1,2]
parseInt(16, 3); // 1
//'16' => '1' (6 ignored because it not in [0,1,2])
/***** Radix 16: Allowed numbers/characters are [0-9,A-F] *****/
parseInt('FOX9', 16); // 15
//'FOX9' => 'F' => 15 (decimal value of 'F')
// all characters from 'O' to end will be ignored once it encounters the out of range'O'
// 'O' it is NOT in [0-9,A-F]
更多示例:
parseInt('45', 13); // 57
// both 4 and 5 are allowed in Radix is 13 [0-9,A-C]
parseInt('1011', 2); // 11 (decimal NOT binary)
parseInt(7,8); // 7
// '7' => 7 in radix 8 [0 - 7]
parseInt(786,8); // 7
// '78' => '7' => 7 (8 & next any numbers are ignored bcos 8 is NOT in [0-7])
parseInt(76,8); // 62
// Both 7 & 6 are allowed '76' base 8 decimal conversion is 62 base 10
我正在阅读 this 但我对 parseInt 中带有基数参数 章节
的内容感到困惑为什么parseInt(8, 3)
→NaN
和parseInt(16, 3)
→1
?
AFAIK 8 和 16 不是基数 3,所以 parseInt(16, 3)
也应该 return NaN
这是人们经常犯的错误,即使他们知道了。 :-) 您看到这个的原因与 parseInt("1abc")
returns 1 相同:parseInt
在第一个无效字符处停止,returns 在该点处的任何内容。如果没有可解析的有效字符,则 returns NaN
.
parseInt(8, 3)
表示"parse "8"
in base 3"(注意它将数字8
转换为字符串;details in the spec)。但是在基数 3 中,个位数只是 0
、1
和 2
。这就像要求它以八进制解析 "9"
一样。由于 没有 个有效字符,您得到 NaN
.
parseInt(16, 3)
要求它在基数 3 中解析 "16"
。因为它可以解析 1
,所以它会解析,然后在 6
处停止,因为它无法解析它。所以它 returns 1
.
由于这个问题受到了很多关注并且可能在搜索结果中排名靠前,这里列出了 JavaScript 中将字符串转换为数字的选项,以及它们的各种特性和应用(摘自另一个答案我在这里的 SO):
parseInt(str[, radix])
- 将字符串的开头尽可能多地转换为一个完整(整数)数字,忽略末尾的额外字符。所以parseInt("10x")
是10
;x
被忽略。支持可选的基数(数字基数)参数,因此parseInt("15", 16)
是21
(十六进制的15
)。如果没有基数,则假定为十进制,除非字符串以0x
(或0X
)开头,在这种情况下它会跳过这些并假定为十六进制。 (一些浏览器曾经将以0
开头的字符串视为八进制;这种行为从未被指定,在 ES5 规范中是 specifically disallowed。) ReturnsNaN
如果找不到可解析的数字。parseFloat(str)
- 与parseInt
相似,但支持浮点数且仅支持小数。字符串上的额外字符再次被忽略,因此parseFloat("10.5x")
是10.5
(x
被忽略)。由于仅支持十进制,因此parseFloat("0x15")
是0
(因为解析在x
处结束)。 ReturnsNaN
如果找不到可解析的数字。一元
+
,例如+str
- (例如,隐式转换) 使用浮点数和 JavaScript 将 整个 字符串转换为数字标准数字表示法(仅数字和小数点 = 十进制;0x
前缀 = 十六进制;0o
前缀 = 八进制 [ES2015+];一些 实现扩展它以处理前导0
作为八进制,但不是在严格模式下)。+"10x"
是NaN
因为x
而不是 被忽略。+"10"
是10
,+"10.5"
是10.5
,+"0x15"
是21
,+"0o10"
是8
[ES2015+] .有一个陷阱:+""
是0
,而不是您可能期望的NaN
。Number(str)
- 完全像隐式转换(例如,像上面的一元+
),但在某些实现上更慢。 (并不是说这很重要。)
出于同样的原因
>> parseInt('1foobar',3)
<- 1
在the doc中,parseInt
接受一个字符串。并且
If string is not a string, then it is converted to a string
因此16
、8
或'1foobar'
首先转换为字符串。
然后
If
parseInt
encounters a character that is not a numeral in the specified radix, it ignores it and all succeeding characters
意味着它会尽可能地转换。 6
、8
、foobar
被忽略,只转换之前的内容。如果什么都没有,则返回NaN
。
/***** Radix 3: Allowed numbers are [0,1,2] ********/
parseInt(4, 3); // NaN - We can't represent 4 using radix 3 [allowed - 0,1,2]
parseInt(3, 3); // NaN - We can't represent 3 using radix 3 [allowed - 0,1,2]
parseInt(2, 3); // 2 - yes we can !
parseInt(8, 3); // NaN - We can't represent 8 using radix 3 [allowed - 0,1,2]
parseInt(16, 3); // 1
//'16' => '1' (6 ignored because it not in [0,1,2])
/***** Radix 16: Allowed numbers/characters are [0-9,A-F] *****/
parseInt('FOX9', 16); // 15
//'FOX9' => 'F' => 15 (decimal value of 'F')
// all characters from 'O' to end will be ignored once it encounters the out of range'O'
// 'O' it is NOT in [0-9,A-F]
更多示例:
parseInt('45', 13); // 57
// both 4 and 5 are allowed in Radix is 13 [0-9,A-C]
parseInt('1011', 2); // 11 (decimal NOT binary)
parseInt(7,8); // 7
// '7' => 7 in radix 8 [0 - 7]
parseInt(786,8); // 7
// '78' => '7' => 7 (8 & next any numbers are ignored bcos 8 is NOT in [0-7])
parseInt(76,8); // 62
// Both 7 & 6 are allowed '76' base 8 decimal conversion is 62 base 10