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

我正在读 这个,但是我对 用基参解析章写的内容感到困惑

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

10022 次浏览

这是人们经常会犯的错误,即使他们知道。: ——)您看到这种情况的原因与 parseInt("1abc")返回1的原因相同: parseInt在第一个无效字符处停止并返回它在该点的所有内容。如果没有要解析的有效字符,则返回 NaN

parseInt(8, 3)的意思是“以3为基数解析 "8"”(注意,它将数字 8转换为字符串; 说明书中的细节)。但是在基数3中,单位数字只有 012。这就像要求它解析八进制的 "9"。因为有 没有有效字符,所以你得到了 NaN

parseInt(16, 3)要求它在基数3中解析 "16"。因为它可以解析 1,所以它可以,然后它停在 6,因为它不能解析它。所以它返回 1


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

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

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

  • 一元 +,例如 +str-< em > (例如,隐式转换) 使用浮点数和 JavaScript 的标准数字符号将 < em > 整个 字符串转换为一个数字(只有数字和小数点 = 十进制; 0x前缀 = 十六进制; 0o前缀 = 八进制[ ES2015 + ] ; < 强 > 一些 实现将其扩展为将前导 0视为八进制,但不是在严格模式下)。+"10x"NaN,因为 x是 < strong > not 忽略的。+"10"10+str0是 +str1,+str2是 +str3,+str4是 +str5[ ES2015 + ]。有一个问题: +str6是 0,而不是 NaN,因为你可能会期望。

  • Number(str)-完全类似于隐式转换(例如,类似于上面的一元 +) ,但在某些实现中速度较慢。(并不是说这有什么关系。)

出于同样的原因

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

医生中,parseInt接受一个字符串

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

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

然后

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

也就是说它能转换到它能转换到的地方。忽略 68foobar,只转换之前的内容。如果没有,则返回 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