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

时间:2016-08-25 13:47:31

标签: javascript numbers parseint radix

我正在阅读this,但我对 parseInt中带有基数参数的内容章节

感到困惑

table of parseInt(_, 3) outcomes

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

AFAIK 8和16不是基数为3的数字,因此parseInt(16, 3)也应该返回NaN

the first ten base-3 natural numbers

3 个答案:

答案 0 :(得分:372)

这是人们一直绊倒的事情,即使他们知道这件事。 :-)您出于同样的原因看到了这一点parseInt("1abc")返回1:parseInt停在第一个无效字符处并返回该点所拥有的内容。如果没有要解析的有效字符,则返回NaN

parseInt(8, 3)表示"在基数3"中解析"8" (请注意,它会将数字8转换为字符串; details in the spec)。但在基数3中,单位数字仅为012。这就像要求它以八进制解析"9"一样。由于没有有效字符,您获得了NaN

parseInt(16, 3)要求它解析基础3中的"16"。因为它可以解析1,它会解析,然后它会停在6,因为它可以& #39; t解析它。所以它返回1

由于这个问题引起了很多关注并且可能在搜索结果中排名很高,因此这里有一个简单的选项,用于将字符串转换为JavaScript中的数字,以及它们的各种特性和应用程序(取决于我的另一个答案)在SO):

  • parseInt(str[, radix]) - 尽可能多地将字符串的开头转换为整数(整数),忽略末尾的额外字符。所以parseInt("10x")10; x被忽略。支持可选的基数(数字基数)参数,因此parseInt("15", 16)21(十六进制为15)。如果没有基数,则假设为十进制,除非字符串以0x(或0X)开头,在这种情况下,它会跳过那些并假定为十六进制。 (某些浏览器用于将以0开头的字符串视为八进制;该行为从未指定,并且在ES5规范中为specifically disallowed。)如果NaN,则返回parseFloat(str)没有找到可解析的数字。

  • parseInt - 与parseFloat("10.5x")类似,但是浮点数并且仅支持小数。字符串上的额外字符将被忽略,因此10.5x(忽略parseFloat("0x15"))。由于仅支持十进制,0x(因为解析在NaN处结束)。如果没有找到可解析的数字,则返回+

  • 一元+str,例如0x - (例如,隐式转换)使用浮点和JavaScript的标准数字表示法将整个字符串转换为数字(只需数字和a小数点=十进制; 0o前缀=十六进制; 0前缀=八进制[ES2015 +]; 一些实现扩展它以将前导+"10x"视为八进制,但不是严格的模式)。 NaNx,因为+"10" 被忽略。 10+"10.5"10.5+"0x15"21+"0o10"8+"" [ES2015 +] 。有一个问题:0NaN,而不是Number(str)正如您所料。

  • + - 完全类似于隐式转换(例如,与上面的一元database.php一样),但在某些实现上速度较慢。 (并非它可能很重要。)

答案 1 :(得分:54)

出于同样的原因

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

the doc中,parseInt需要一个字符串。和

  

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

首先将168'1foobar'转换为字符串。

然后

  

如果parseInt遇到的字符不是指定基数中的数字,则会忽略它和所有后续字符

意味着它可以转换到可以的位置。 68foobar将被忽略,只转换之前的内容。如果没有,则返回NaN

答案 2 :(得分: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