web-dev-qa-db-ja.com

parseInt(8,3)== NaNおよびparseInt(16,3)== 1なのはなぜですか?

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

table of parseInt(_, 3) outcomes

parseInt(8, 3)NaNおよびparseInt(16, 3)1なのはなぜですか?

AFAIK 8および16は3進数ではないため、parseInt(16, 3)NaNも返す必要があります

the first ten base-3 natural numbers

191
Devid Farinelli

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

parseInt(8, 3)は、「ベース3の"8"を解析する」ことを意味します(数値8を文字列に変換することに注意してください; 仕様の詳細 )。しかし、基数3では、1桁の数字は01、および2だけです。 "9"を8進数で解析するように依頼するようなものです。有効な文字noがあったため、NaNが得られました。

parseInt(16, 3)は、ベース3で"16"を解析するように求めています。1を解析できるので、解析できず、6で停止します。したがって、1を返します。


この質問は多くの注目を集めており、検索結果で非常にランク付けされる可能性があるため、JavaScriptで文字列を数値に変換するためのオプションの概要を、さまざまな特異性とアプリケーションと共に示します(SOに関する私の別の回答から抜粋):

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

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

  • 単項+、例: +str-(たとえば、暗黙の変換)entire文字列を、浮動小数点とJavaScriptの標準の数値表記を使用して数値に変換します(数字と小数点= 10進数; 0xプレフィックス= hex; 0o prefix = octal [ES2015 +];some実装は、それを拡張して、先頭の0を8進数として扱いますが、厳密モードではありません。 +"10x"は、NaNnot無視されるため、xです。 +"10"10+"10.5"10.5+"0x15"21+"0o10"8 [ES2015 +]です。落とし穴があります:+""0であり、NaNではありません。

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

372
T.J. Crowder

同じ理由で

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

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

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

したがって、168、または'1foobar'は最初に文字列に変換されます。

それから

parseIntは、指定された基数の数字ではない文字に遭遇した場合、それとそれ以降のすべての文字を無視します

意味はできる限り変換します。 68、およびfoobarは無視され、前のもののみが変換されます。何もない場合、NaNが返されます。

54
njzk2