Javascriptの勉強をし直しているので,分かってなかったことなんかをメモしています。
今回は,数値計算とかでよく出てくる浮動小数点について調べてみました。

MozillaのMDN Javascript再入門
によると,

JavaScript における数値は,仕様によると「倍精度 64 ビットフォーマット IEEE 754 値 (double-precision 64-bit format IEEE 754 values)」です。

と,いきなり難しいことを言ってきます…。
ということで,以下に調べてみた結果をメモ。

目次

  1. IEEE 754
  2. 不動小数点とは
  3. IEEE 754における浮動小数点
  4. 固定小数点を浮動小数点に変換
    1. 10進数から2進数
    2. 2進数を「1.◯◯×2^△」にする
  5. Javascriptでは……
  6. 参照サイト

IEEE 754

IEEE=「Institute of Electrical and Electronics Engineers=米国電気電子技術者協会」の略。
IEEEは電気工学を源流とする通信・電子・情報工学とその関連分野の学会であり,事実上コンピューターの色々な仕様の世界標準決定機関です。
で,「IEEE754」は,この学会が取り決めた「 浮動小数点演算に関する標準規格」です。

不動小数点とは

コンピューターは厳密には「0」と「1」で構成される2進数しか扱えません。
そこで,(小数点を含む)整数を表すのに特別な方法が必要となってきます。

小数点を表すには固定小数点数と浮動小数点数があります。
固定小数点とは,普段よく目にする「3.1424,,,,,」のように表現すること。
この方式ではコンピューターが理解することができません。

一方,不動小数点では「指数形式(○○×△△の□□乗)」という形で表します。
具体的には,「3.14」を表すのに「31.4×10-1,314.0×10-2,3.14×100,31.4×10-1,314.0×10-2,,,」と色んな形で表現することができます。
表現する形が多いということは,コンピューターやソフトを作るときに作り手が好き勝手に決められることになります。
ところが,それでは互換性とかの問題で扱いにくいのでIEEEが基準を示し,作り手がそれを採用して互換性を保つようになりました。

ということで,以下はIEEE745に沿った浮動小数点です。

IEEE 754における浮動小数点

浮動小数点で表現するのに,指数形式を部分的に分けて使います。
「○○×△△の□□乗」は

  • ○○を仮数部(符号)
  • △△を基数部
  • □□乗を指数部

と呼びます。
そして,求められる計算精度とデータ容量の問題を考慮して以下の2つの形式が定められています。

  • 半精度浮動小数点数では,符号部 1 ビット ・ 指数部 5 ビット ・ 仮数部 10 ビット =16ビット
  • 単精度浮動小数点数では,符号部 1 ビット ・ 指数部 8 ビット ・ 仮数部 23 ビット =32ビット
  • 倍精度浮動小数点数では,符号部 1 ビット ・ 指数部 11 ビット ・ 仮数部 52 ビット =64ビット
  • 四倍精度浮動小数点数では,符号部 1 ビット ・ 指数部 15 ビット ・ 仮数部 112 ビット=127ビット

として扱います。
最近よく言われる「32bit版Windows10」「64bit版Windows10」といのは,ここに由来しています。
さらに,

  • 符号部は「正の値なら0」,「 負の値なら1」とする。
  • 仮数部は,整数部分が 1 であるような2進小数の小数部分(ケチ表現)を表す。
  • 指数部は,符号なし2進整数とし,半精度では 15,単精度では 127,倍精度では 1023,四倍精度では 16383 のゲタを履かせたゲタ履き表現で表す。

固定小数点を浮動小数点に変換

実際に単精度で「3.25」を浮動小数点に変換してみます。

10進数から2進数

10進数を整数と小数点以下の2つに分けます。
理由は,それぞれ2進数に直す方法が異なるから。
整数はひたすら2で割りその余りを出します。
3を2進数にすると,

1
2
3/2→1余り1
1/2→0余り1

並びは下からなので,答えは「11」となります。

続いて小数点以下を2進数にします。
方法は10進数の小数部を2倍して商を求めます。
商の小数部を繰り返し2倍していき,その整数部が2進数になります。
つまり,「0.25」を計算すると

1
2
0.25*2→0.5 整数部0
0.5*2→1 整数部1

並びは整数とは逆で上から読むので,答えは「01」となります。
よって,「3.25」の2進数は「11.01」となります。

2進数を「1.◯◯×2^△」にする

  • 符号は正の数なので「0」。
  • 指数は2に小数点を動かした桁と同数に127(単精度)を足すので,「1+127=128」とります。

128を2進数に直すと

1
2
3
4
5
6
7
8
128/2→64余り0
64/2→32余り0
32/2→16余り0
16/2→8余り0
8/2→4余り0
4/2→2余り0
2/2→1余り0
1/2→0余り1

よって答えは「1000 0000」。

仮数は整数部が「1」固定の2進数になるように小数点を左に移動するので,1.101。 これを「正規化」といいます。
仮数は23ビット(単精度)で小数点より右側だけなので,足りない分を0でうめて101000000000 00000000000

浮動小数点は符号,指数,仮数を合わせて01000000010100000000000000000000となります。
以上で,「3.25」を32bitの浮動小数点に変換できました。

Javascriptでは……

冒頭のJavascriptの「数値」の扱いの仕様に戻ると「倍精度 64 ビットフォーマット」で扱うとなってます。
ところが,読み進めると

実のところ,整数値は 32 ビット int 型として扱われます。また一部の実装では,32 ビット整数値ではなく Number で有効な命令の実行を求められるまでの間,32 ビット整数値として保存します。これはビット演算を行う際に重要なことです。

とあります。
よくわかりません。^^;
とりあえず,長くなったので項目を改めます。

参照サイト

ITpro『【5分で覚えるIT基礎の基礎】ゼロから学ぶ2進数 第4回』
一から勉強させてください( ̄ω ̄;)
MDN Javascript再入門