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) といった指数表記の文字列が返ってきます。この方法で得られる文字列には偏りがあります

参考

コメント

コメントをどうぞ

※メールアドレスとURLの入力は必須ではありません。 入力されたメールアドレスは記事に反映されず、ブログの管理者のみが参照できます。

※投稿には管理者が設定した質問に答える必要があります。

名前:
メールアドレス:
URL:
次の質問に答えてください:
「ハイパーテキストマークアップ言語」をアルファベット4文字でいうと?

コメント:

トラックバック

このエントリのトラックバックURL: http://nanto.asablo.jp/blog/2007/08/17/1731754/tb