12

『 Game Engine Architecture 』という本の中で: 「...たとえば、浮動小数点変数を使用して絶対ゲーム時間を秒単位で追跡するとします。クロック変数の大きさが大きくなりすぎて 1/30 を加算するまで、ゲームを実行できる時間はどれくらいですか? 1秒遅れても価値が変わらない? 答えはおおよそ12.9日」なぜ12.9日なのか、計算方法は?

4

3 に答える 3

9

浮動小数点計算の結果を正確に表すことができない場合、最も近い値に丸められます。したがって、増分f = 1/30 がxと次に大きい float の間の幅hの半分未満になるように、最小値xを見つけたいとします。つまり、 x+fはxに丸められます。

ギャップは同じbinade内のすべての要素で同じであるため、 xはその binade 内の最小の要素 (2 の累乗) でなければならないことがわかります。

したがって、x = 2 kの場合、 floatには 24 ビット仮数があるため、h = 2 k-23となります。したがって、最小の整数kを見つける必要があります。

2 k-23 /2 > 1/30

これは、 k > 19.09 を意味するため、k = 20、x = 2 20 = 1048576 (秒) となります。

x / (60 × 60 × 24) = 12.14 (日) であることに注意してください。これは、回答が提案するものよりも少し少ないですが、経験的にチェックアウトします: Julia で

julia> x = 2f0^20
1.048576f6

julia> f = 1f0/30f0
0.033333335f0

julia> x+f == x
true

julia> p = prevfloat(x)
1.04857594f6

julia> p+f == p
false

更新: では、12.9 はどこから来たのでしょうか? 12.14 は実際の時間ではなく、ゲーム時間です。これらは、浮動小数点に含まれる丸め誤差のために発散します (特に、丸め誤差が実際にはfに比べて非常に大きい場合)。私の知る限り、これを直接計算する方法はありませんが、実際には 32 ビット浮動小数点数を反復処理するのはかなり高速です。

再び、ジュリアで:

julia> function timestuff(f)
           t = 0
           x = 0f0
           while true
               t += 1
               xp = x
               x += f
               if x == xp
                   return (t,x)
               end
           end
       end
timestuff (generic function with 1 method)

julia> t,x = timestuff(1f0/30f0)
(24986956,1.048576f6)

xは、以前に計算した結果と一致しt、30 秒単位のクロック タイムです。日への換算:

julia> t/(30*60*60*24)
9.640029320987654

それはさらに遠くにあります。12.9がどこから来たのかわかりません...

更新 2: 私の推測では、12.9 は計算によるものです。

y = 4 × f / ε = 1118481.125 (秒)

ここで、ε は標準のマシン イプシロン(1 と次に大きい浮動小数点数の間のギャップ) です。これを日数に換算すると、12.945 になります。これはxの上限を提供しますが、上で説明したように正解ではありません。

于 2016-05-25T21:05:00.660 に答える
1

これは、浮動小数点表現の表現可能性のゾーンによるものです。私の大学からのこの講義をチェックしてください。

指数が大きくなるにつれて、実際に表される値の間の実数直線上のジャンプが増加します。指数が低い場合、表現の密度は高くなります。例を挙げると、有限個の桁の値を持つ 10 進数をイメージします。1.0001e1 と 1.0002e1 の場合、2 つの値の差は 0.0001 です。しかし、指数が 1.0001-10 1.0002-10 増加すると、2 つの差は 0.000100135 になります。明らかに、指数が増加するにつれて、これは大きくなります。あなたが話している場合、ジャンプが非常に大きくなる可能性があり、増加しても最下位ビットの丸め増加は促進されません

興味深いことに、表現の限界に向かって、より大きな float 型の精度が低下します! 単純に、指数に使用できるビットが増えると、仮数部のビット パターンの増加が数直線上でさらにジャンプするためです。double の場合と同様に、オーバー フロート

于 2016-05-25T19:20:14.153 に答える