为什么parseInt(8,3)== NaN和parseInt(16,3)== 1?


191

我读这个,但我通过什么是写在混淆parseInt函数与基数参数章节

parseInt(_,3)结果表

为什么parseInt(8, 3)NaNparseInt(16, 3)1

据我所知8和16都没有基本的3个数字,所以parseInt(16, 3)应该返回NaN

前十个以3为底的自然数


4
静态输入可以解决另一个问题(或至少不是将整数隐式转换为字符串):P
Navin,2016年

4
@Navin这与静态类型和动态类型无关(如您所知)。与强类型相比,这里的问题是弱的。
斯文·马纳赫

12
当我看到这个问题的标题时,我心想:“这可能是因为loljavascript”。看到答案,我认为本能基本上是正确的。
本·米尔伍德

Answers:


373

人们一直在旅行,即使他们知道这一点。:-)出于相同的原因,您会看到以下内容parseInt("1abc"):返回1:parseInt停在第一个无效字符处,然后返回此时的所有内容。如果没有要解析的有效字符,则返回NaN

parseInt(8, 3)表示“ "8"以3为底分析”(请注意,它将数字8转换为字符串;有关详细信息,请参见spec)。但在以3为底的数字中0,个位数分别是1,和2。就像要求它解析"9"为八进制。由于没有有效的字符,您得到了NaN

parseInt(16, 3)要求它以"16"3为底进行解析。由于它可以解析1,所以可以,然后在处停止,6因为它无法解析。因此它返回1


由于这个问题引起了广泛关注,并且在搜索结果中可能排名很高,因此下面列出了在JavaScript中将字符串转换为数字的选项以及它们的各种特质和应用程序(从我这里关于SO的另一个答案中得出):

  • parseInt(str[, radix])-将字符串的开头尽可能多地转换为整数(整数),而忽略结尾的多余字符。所以parseInt("10x")10; 该x被忽略。支持可选的基数(基数)参数,(十六进制)parseInt("15", 16)也是如此。如果没有基数,则假定为十进制,除非字符串以(或)开头,在这种情况下,它会跳过这些并假定为十六进制。(某些浏览器过去将字符串以八进制开头;该行为从未指定,在ES5规范中特别禁止。)如果未找到可解析的数字,则返回。21150x0X0NaN

  • parseFloat(str)-和一样parseInt,但是浮点数并且仅支持十进制。再串上多余的字符被忽略,所以parseFloat("10.5x")10.5(将x被忽略)。由于仅支持十进制,所以parseFloat("0x15")0(因为解析在处结束x)。NaN如果找不到可解析的数字,则返回。

  • 一元+,例如+str- (例如,隐式转换)使用浮点数和JavaScript的标准数字符号将整个字符串转换为数字(仅数字和小数点=十进制;0x前缀=十六进制;0o前缀=八进制[ES2015 +];某些实现对其进行了扩展将前导0视作八进制,而不是严格模式)。+"10x"NaN因为x忽略。+"10"10+"10.5"10.5+"0x15"21+"0o10"8[ES2015 +]。有一个陷阱:+""0NaN与您预期的不同。

  • Number(str)-就像隐式转换一样(例如,像+上面的一元转换一样),但是在某些实现上比较慢。(这并不重要。)


8
那么parseInttoString一个参数的第一个用法是?那是有道理的。
evolutionxbox

16
@evolutionxbox:是的,这是第一步parseInt算法:ecma-international.org/ecma-262/7.0/...
TJ克罗德

5
我想123e-2给出,1因为它先变成了1.23,然后解析停在小数点?
ilkkachu

6
“这是人们一直旅行的东西,即使他们知道这一点也是如此”->我是唯一认为这应该是错误的人吗?例如,在Java中执行相同操作会给您NumberFormatException每次的机会。
Wim Deblauwe

4
@SvenMarnach:的一部分parseInt(将第一个参数强制为字符串)是有意义的。的目的parseInt是将字符串解析为整数。因此,如果您给它提供的不是字符串,则以它的字符串表示形式开头是很有意义的。它的作用之后是一个整体“诺特尔故事...
TJ克罗德

54

出于同样的原因

>> parseInt('1foobar',3)
<- 1

doc中,使用parseInt一个字符串。和

如果字符串不是字符串,则将其转换为字符串

因此16,,8'1foobar'首先转换为字符串。

然后

如果parseInt遇到指定基数中非数字的字符,它将忽略该字符以及所有后续字符

意味着它可以转换到它可以达到的最大位置。的68以及foobar被忽略的,只有什么是之前被转换。如果什么都没有,NaN则返回。


0
/***** 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 
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.