90年代前半、3次元ゲームエンジンの作成は、マシンにほとんど特徴のないタスクを実行させることを意味していました。 当時のパーソナルコンピューターは、ワードプロセッサとスプレッドシートを実行するように設計されており、1秒あたり70フレームの頻度で3Dコンピューティングを行うためのものではありませんでした。 深刻な障害は、そのパワーにもかかわらず、CPUに浮動小数点計算用のハードウェアデバイスがなかったことです。 プログラマーにはALU研削整数しかありませんでした。
Game Engine Black Book:Wolfenstein 3D bookを書くとき、浮動小数点なしで作業するときの問題の大きさを示したかったのです。 正規の 記事を使用して浮動小数点数を理解しようとする私の試みは、敵意をもって脳によって認識されました。 私は別の方法を探し始めました。 遠いもの (−1)S∗1.M∗2(E−127) そして、仮数を持つそれらの不可解な指数。 私の脳はそれらをより簡単に知覚するので、たぶん図面の形で。
その結果、私はこの記事を書き、本に追加することにしました。 これが私の発明だと主張するつもりはありませんが、これまでのところ、浮動小数点数のそのような説明を見たことはありません。 この記事が、私のように数学表記にアレルギーのある人に役立つことを願っています。
浮動小数点数は通常説明されているので
David Goldbertの言葉を引用します。
多くの人にとって、浮動小数点演算はある種の秘密の知識のように思えます。
私は彼に完全に同意します。 ただし、3Dエンジンをプログラミングする際にその有用性を完全に実現するには、その作業の原理を理解することが重要です。 Cでは、浮動小数点値はIEEE 754標準に準拠する32ビットのコンテナーであり、実数の近似値の演算を保存および実行するように設計されています。 これまでのところ、私はそれらの説明だけを見てきました。 32ビットは3つの部分に分かれています。
- 文字ストレージ用のS(1ビット)
- 指数のE(8ビット)
- 仮数のM(23ビット)
浮動小数点数の内部。
浮動小数点数の3つの部分。
これまでのところ、とても良い。 続けましょう。 数値の解釈方法は、通常、次の式を使用して説明されます。
(−1)S∗1、M∗2(E−127)
誰もが嫌うのは、この浮動小数点数の説明です。
そして、ここで私は通常忍耐を失い始めます。 私は数学的表記法にアレルギーがあるかもしれませんが、それを読んだとき、私の脳は何もクリックしません。 この説明は、フクロウが描かれる方法に似ています。
別の説明方法
これは事実ですが、浮動小数点数を説明するこの方法では、通常は理解できません。 何千人ものプログラマーを失望させ、浮動小数点計算が実際にどのように機能するかを二度と理解しようとはしなかったという点で、この恐ろしい記録を非難します。 幸いなことに、それらは異なって説明することができます。 指数は、ウィンドウまたは2つの隣接する2のべき乗間の間隔と考えてください。 このウィンドウでは、仮数はオフセット(オフセット)と考えてください。
浮動小数点数の3つの部分。
ウィンドウは、2つの連続する2の累乗の間の数を示します:[0,1]、[1,2]、[2,4]、[4,8]など([ 2127 、 2128 ]。 オフセットはウィンドウを分割します 223=8388608 セグメント。 ウィンドウとオフセットを使用して、数値を概算できます。 ウィンドウは、国境通過を防ぐための優れたメカニズムです。 ウィンドウ内で最大値に達したら(たとえば[2,4]で)、右に「泳ぐ」ことができ、次のウィンドウ(たとえば[4,8])で数値を表示できます。 ウィンドウのサイズが2倍になるため、この価格は精度のわずかな低下にすぎません。
クイズ:ウィンドウがより長い間隔を閉じるとどれくらいの精度が失われますか? ウィンドウ[0,1]の例を見てみましょう。ここでは、サイズ1の間隔に8388608のオフセットが重ねられており、精度が得られます。 frac(1−0)8388608=$0.0000001192092 。 [2048.4096]ウィンドウでは、間隔に8388608オフセットが重畳されます (4096−2048)=$204 それは私たちに正確さを与えます frac(4096−2048)8388608=$0,000 。
次の図は、数値6.1のエンコード方法を示しています。 ウィンドウは4で始まり、次の2の累乗で終わるはずです。 8.オフセットはウィンドウのほぼ中央にあります。
浮動小数点数で近似された6.1の値。
私たち全員によく知られている値を浮動小数点数として表すことにより、詳細な計算を行うもう1つの例を見てみましょう。3.14。
- 数値3.14は正です \右矢印S=0 。
- 数値3.14は、2の2と4の累乗の間です。つまり、浮動小数点数ウィンドウは、 21\右矢印E=128 (ウィンドウがある式を参照してください 2(E−127) )
- 最後にそこに 223 間隔内の3.14の位置を表すことができる変位[2-4]。 にあります frac3,14−24−2=$0.5 オフセットを与える間隔内 M=223∗0.57=$4,781,50
バイナリでは、これは次のように変換されます。
- S = 0 = 0b
- E = 128 = 10000000b
- M = 4781507 = 10010001111010111000011b
浮動小数点数のバイナリ表現は3.14です。
つまり、3.14の値は3.1400001049041748046875として近似されます。
理解できない式の対応する値:
3.14=(−1)0∗1.57∗2(128−127)
そして最後に、ウィンドウとオフセットを含むグラフィカルな表現:
ウィンドウと数値オフセット3.14。
興味深い事実:浮動小数点演算モジュールが非常に遅い場合、なぜC言語はfloat型とdouble型を使用したのですか? 実際、言語が発明されたマシン(PDP-11)には、浮動小数点演算用のモジュールはありませんでした! 事実、メーカー(DEC)はデニスリッチーとケントンプソンに次のモデルに参加することを約束しました。 彼らは天文学愛好家であり、これら2つのタイプを言語に追加することにしました。
興味深い事実: 1991年に浮動小数点演算にハードウェアモジュールを本当に必要としていた人は、それを買うことができました。 当時それを必要としていたのは科学者だけでした(少なくとも、Intelは市場のニーズを理解していました)。 市場では、彼らは自分自身を「数学的なコプロセッサー」と位置付けました。 彼らのパフォーマンスは平均的で、価格は莫大です(1993年に200ドル-2016年に350ドルです)。 その結果、販売レベルは平凡でした。
この記事がお役に立てば幸いです!