JavaScript で n 進数を扱う ― 2007年08月17日 18時01分
2 進数や 16 進数を使いたいというとき、JavaScript では組み込みの機能を利用できます。使えるのは 16 進数だけではなく、2 進数から 36 進数 (0 ~ 9 および a ~ z を使用) まで扱えます。
n 進数文字列から数値への変換
n 進数文字列から数値へと変換するときは、parseInt 関数を使います。第 2 引数に基数 n を指定することで、第 1 引数の文字列を n 進数であると解釈してくれます。n は 32 ビット整数に変換され、その値が 2 未満または 36 を超えるときは NaN が返ります。ただし、n が 0 になるときは文字列が 10 進数表記であるとして解釈されます。
parseInt(10, 36); // 36
parseInt("10", 0x100000000 + 36); // 36
基数が明示されておらず、文字列が 0 から始まっていた場合、ECMAScript では 8 進数として解釈することを認めつつも 10 進数として解釈することを推奨しています。一方、この場合 JavaScript では、8 進数として解釈することとした上で、それを非推奨であるとしています。
parseFloat 関数には基数を指定することができず、小数部を保持したまま n 進数表記の小数を数値化することはできません。
余談ですが、anarachy golf banner での 2007 年 3 月 8 日時点での JavaScript の記録 (278 バイト) では、データサイズを減らすため数値データを 36 進数文字列として格納し、parseInt を使ってそれを数値化しています。
数値から n 進数文字列への変換
toString メソッドの引数に基数を指定することで、数値を n 進数表記の文字列に変換できます。ECMAScript では、10 を除く 2 ~ 36 の整数が基数として指定されたときの動作は実装依存、その他の値が指定された時の動作は未定義となっていますが、多くの実装では整数の 2 ~ 36 進数表現への変換に対応しています。小数の変換に対応している実装もあります。
10 .toString(16); // "a"
2..toString(2); // "10" ("2." が数値リテラルとして解析される)
各ブラウザの実装
各ブラウザにおける Number#toString の実装状況一覧を作成しました。表から、各ブラウザの実装は以下のようになっているものと推測されます。
- IE 7 (JScript)
-
- 基数を 32 ビット整数に変換する。
- 基数が範囲外の場合、例外を投げる。
- 小数部も n 進数表記に変換する。
- Firefox 2.0.0.6 (SpiderMonkey)
-
- 基数を 32 ビット整数に変換する。
- 基数が範囲外の場合、例外を投げる。
- 小数部も n 進数表記に変換する。
- Opera 9.23
-
- 基数を 32 ビット整数に変換する。
- 基数が範囲外の場合、基数として 10 を用いる。
- 変換する数に小数部が含まれる場合、基数として 10 を用いる。
- Safari 3.0.3 Beta (JavaScriptCore)
-
- 基数を整数に変換する。
- 基数が範囲外の場合、基数として 10 を用いる。
- 小数部も n 進数表記に変換する。
- Safari 2.0.4 (JavaScriptCore)
-
- 基数を整数に変換する。
- 基数が範囲外の場合、基数として 10 を用いる。
- 基数が 10 を除く 2 ~ 36 の整数の場合、変換する数を 32 ビット符号なし整数に変換する。
これを利用すると、Firefox では、(Number.MAX_VALUE * Math.random()).toString(36)
とすることにより、大体の確率で 197 ~ 199 桁くらいのランダムな英数字列を生成することができます。ただし、IE で同様のことを行うと、m.plkf48n2dcw(e+197) といった指数表記の文字列が返ってきます。この方法で得られる文字列には偏りがあります。
最近のコメント