JavaScriptのparseFloat()とparseInt()について、仕様を参照しつつ、適当な値を渡して何を返すか実験してみる。
parseFloat(string)の仕様
仕様では、parseFloat()は以下のような処理を実行するよう定められている。
- 引数に渡された値を文字列に変換する。
- 変換した文字列の前後の空白を削除する。
- 空白を削除した文字列をUnicodeコードポイントの配列に変換する。
+あるいは-、あるいは数値で始まる10進数の文字列を、先頭から可能な限り長く取得する(取得できない文字列はNaNを返す)。- パースした浮動小数点数を返す。
上記の通り、parseFloat()は、渡された文字列の先頭から数値(10進数リテラル)に解釈できるものを取り出し、解釈できなかった時点で処理を止める。10進数リテラルに解釈できなかった部分はただ無視され、そのことに対する情報は示されない。
parseInt(string, radix)の仕様
parseInt()の仕様は、以下のような手順を定めている。
- 第1引数に渡された値を文字列に変換する。
- 変換した文字列の前後の空白を削除する。
- 符号を
1にする。 - 文字列の先頭が
0x002D(HYPHEN-MINUS)なら、符号を-1にする。 - 文字列の先頭が
0x002B(PLUS SIGN)か0x002D(HYPHEN-MINUS)なら、文字列をインデックス1からの部分文字列と解釈する。 - 第2引数に渡された基数を、32ビット整数に変換する。
stripPrefixフラグ(接頭辞を削除するかどうか)をtrueとする。- 基数が
0でなく、2より小さい、あるいは36より大きいとき、NaNを返す。 - 基数が
0でなく、16でもないとき、stripPrefixフラグをfalseとする。 - 基数が
0のとき、基数を10とする。 stripPrefixフラグがtrueのときで、文字列の長さが2以上かつ文頭が0xか0Xのとき、文字列をインデックス2からの部分文字列と判断し、基数を16とする。- ここまでに定まった基数桁に含まれる数字を先頭から探していき、該当しない文字を見つけた時点で終端と判断する。
- もし文頭から終端までが空なら、
NaNを返す。 - パースした整数を定まった基数で計算し直し、10進数を返す(負数の場合のみ
-がつく。また、20桁以上桁は0としても良い)。
parseFloat()と同じく、文頭の+と-を除き、指定された基数の桁に含まれない文字はただ無視される。
返す値のサンプル
当然だが、仕様の通りである。parseInt()に渡す基数が変わると、NaNだった文字列が急に意味を持つのが地味におもしろく、直感的に理解しづらい。
例えばparseInt(102, 2)の返り値は2となる。処理の流れとしては、まず102の先頭から2進数が探され、10が取得される。次に2進数の10が10進数に直されて2となり、これが返される。
整理してみたらわりと簡単だった。わかりづらいと感じたのは私だけかもしれない。