parseInt(8,3)== NaNであり、parseInt(16,3)== 1であるのはなぜですか?


191

私はこれを読んでいますが、parseIntの基数引数の章に何が書かれているか混乱しています。

parseInt(_、3)結果のテーブル

なぜそれがということですparseInt(8, 3)NaNparseInt(16, 3)1

AFAIK 8と16は3を基数としないため、parseInt(16, 3)戻る必要がありNaNます。

最初の10のbase-3自然数


4
静的型付け(または少なくとも暗黙的に整数を文字列に変換しないこと)によって解決されたさらに別の問題:P
Navin

4
@Navinこれは、静的な型付けと動的な型付けとは何の関係もありません(ご存知のとおり)。ここでの問題は、強い型付けとは対照的に弱いものです。
Sven Marnach 16

12
この質問のタイトルを見たとき、「たぶんloljavascriptが原因だ」と思いました。自分の本能は基本的に正しかったと私が判断した答えを見てください。
ベンミルウッド2016

回答:


373

これは、人々がそれを知っていても、つねに旅行するものです。:-)同じ理由でこれが表示されるのは、parseInt("1abc")1が返される場合です。parseInt最初の無効な文字で停止し、その時点で何があるかを返します。解析する有効な文字がない場合は、を返しますNaN

parseInt(8, 3)"8"base 3で解析」を意味します(数値8を文字列に変換することに注意してください仕様の詳細)。しかし、ベース3に、一桁の数字だけであり012"9"8進数で解析するように要求するようなものです。有効な文字がなかったため、を取得しましたNaN

parseInt(16, 3)"16"、base 3で解析するように要求しています。は解析できるため、解析し、解析できないため1、で停止し6ます。したがって、それは戻ります1


この質問は非常に注目を集めており、検索結果で上位にランク付けされる可能性があるため、JavaScriptで文字列を数値に変換するためのオプションの概要を以下に示します。

  • parseInt(str[, radix])-文字列の先頭を可能な限り整数(整数)の数値に変換し、末尾の余分な文字を無視します。そうparseInt("10x")です10; これxは無視されます。オプションの基数(基数)引数をサポートしているためparseInt("15", 16)211516進数で)です。基数がない場合、文字列が0x(または0X)で始まらない限り、10進数であると想定します。その場合、それらはスキップされ、16 進数であると想定されます。(一部のブラウザは0、8進数で始まる文字列を処理するために使用されていました。その動作は指定されてNaNおらず、ES5仕様で特に禁止されていました。)解析可能な数字が見つからない場合に返されます。

  • parseFloat(str)-に似てparseIntいますが、浮動小数点数を処理し、10進数のみをサポートします。再び文字列に余分な文字はそう、無視されparseFloat("10.5x")ている10.5x無視されます)。サポートされているのparseFloat("0x15")は10進数のみな0ので、です(解析はで終了するためx)。NaN解析可能な数字が見つからない場合に返します。

  • 単項+、例えば+str- (例:暗黙的な変換)浮動小数点とJavaScriptの標準の数値表記(数字と小数点のみ= 10進数、接頭辞= 16進数、接頭辞= 8進数[ES2015 +]、一部の実装では拡張)を使用して文字列全体を数値に変換します。先行を8進数として扱うが、厳密モードでは扱いません)。ですので、されていない無視。is 、is 、is 、is [ES2015 +]です。落とし穴があります:は、予想どおりではありません。0x0o0+"10x"NaNx+"10"10+"10.5"10.5+"0x15"21+"0o10"8+""0NaN

  • Number(str)-暗黙の変換とまったく同じ(たとえば、+上記の単項のような)が、一部の実装では遅い。(それが問題になる可能性が高いというわけではありません。)


8
だから、parseInt最初の使用のtoString最初の引数に?それは理にかなっています。
evolutionxbox

16
@evolutionxbox:うん、それは最初のステップですparseIntアルゴリズム:ecma-international.org/ecma-262/7.0/...
TJクラウダー

5
それが最初になってから解析が小数点で停止するので、私は123e-2与えると思いますか?11.23
ilkkachu 2016

6
「これは、人々がそれについて知っていても、つねにつまづくものです」->これがバグであると思うのは私だけですか?たとえば、Javaで同じことを行うと、NumberFormatException毎回得られます。
Wim Deblauwe 16

4
@SvenMarnach:(最初の引数を文字列に強制する)のその部分parseIntは理にかなっています。の目的は、文字列を整数parseInt解析することです。したがって、文字列ではないものを指定する場合、その文字列表現を最初に取得することには意味があります。それは何の後にそれが...話Notherの」全体で
TJクラウダー

54

同じ理由で

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

ではドキュメントparseInt文字列を取ります。そして

文字列文字列でない場合、文字列に変換されます

ですから168または'1foobar'最初の文字列に変換されます。

その後

parseInt指定された基数で数字ではない文字を検出した場合、その文字と後続のすべての文字を無視します

それができるところまで変換するという意味です。68foobar無視され、唯一の前に何を変換されています。何もない場合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 
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.