Unity で「情報落ち」を再現してみる
情報落ち
浮動小数点数では、大きな数と小さな数の足し算を行うと結果として小さな数が足されなかったことが起きます。
c = a + b // a:Large Number ,b:Small Number
c == a // True (??)
Unity で再現してみる
[Github] note-nota/InformationLoss
カメラの前に四角い箱があってクルクル回るシーン。
Cube には下記のスクリプトがアタッチされています。
void Update()
{
rotation_deg += speed_deg * Time.deltaTime;
transform.rotation = Quaternion.Euler(0f, rotation_deg, 0f);
}
これにより、y 軸周りの回転だけがスムーズに行われる…と思いきや、あるとき回転が止まる。
speed_deg
を大きくするとまた動き出します。
説明してみる
先人の知恵を拝借して、少しばかり説明してみる。
浮動小数点型では「指数部」と「仮数部」に分けて実数を表現する。
float\mbox{ の表す値} = (-1)^{符号部} × 2^{指数部-127} × 1.\mbox{ 仮数部}
float であれば 4 バイト(32 ビット)であり、2のべき乗以下の数を表現する仮数部は 23 ビットの精度でしか表現できない。$2^{23} = 8,388,608$ なので、おおむね7桁程度の精度しかもっていないことになる。そのため、7桁以上の大きな開きがある足し算をするとこの仮数部では表現できない、という状況が発生します。これが、「情報落ち」。
今回の Unity の例では、rotation_deg
が非常に大きな値 (1.677 e+07) のため、足す値 speed_deg * Time.deltaTime
が $\mathcal{O}_{(1)}$ 程度で「足し算の結果、足した値が反映されていない!」状況になります。
Author And Source
この問題について(Unity で「情報落ち」を再現してみる), 我々は、より多くの情報をここで見つけました https://qiita.com/note-nota/items/cd67e481dc973e88ccf7著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .