浮動小数点の情報落ち対策をしない場合とした場合でどれくらい差がでるのか興味が湧いたので試してみました。
1秒毎に測定した気温の3分間の移動平均計算を想定して25前後の乱数を180個つくり、情報落ち対策をしなかった平均値ave1と情報落ち対策をしたave2の差diffを表示するようにしてみました。
結果としてはe-14~e-15のオーダーに違いが見られました。情報『落ち』というぐらいだから常にave1≦ave2かと思っていましたが、ave1の方が大きくなる場合もあるんですね。
なお、情報落ち対策の計算方法は以下のサイトを参考にさせて頂きました。感謝。
https://www.cc.kyoto-su.ac.jp/~yamada/programming/float.html
for {set j 0} {$j < 10} {incr j} {
for {set i 0} {$i < 180} {incr i} {
lappend values [expr {rand() * 50 + rand()}]
}
set n [llength $values]
set ave1 [expr ([join $values +])/$n]
set ave2 0.0
set losted 0.0
foreach value $values {
set actual [expr {($losted + $value) + $ave2}]
set losted [expr {($losted + $value) - ($actual - $ave2)}]
set ave2 $actual
#puts [format "losted=%+.17f" $losted]
}
set ave2 [expr {$ave2 / $n}]
puts [format "ave1 = %.17f\nave2 = %.17f\ndiff = %+.17f\n" $ave1 $ave2 [expr {$ave1-$ave2}]]
}
出力例は以下の通り。乱数を使っているので、結果は毎回異なりますが。
ave1 = 25.07280401240855028
ave2 = 25.07280401240854673
diff = +0.00000000000000355
ave1 = 25.00120967717174381
ave2 = 25.00120967717172960
diff = +0.00000000000001421
ave1 = 25.27157371650008599
ave2 = 25.27157371650005757
diff = +0.00000000000002842
ave1 = 25.37179051766786841
ave2 = 25.37179051766785776
diff = +0.00000000000001066
ave1 = 25.79864019810365150
ave2 = 25.79864019810365505
diff = -0.00000000000000355
ave1 = 25.67349073410403548
ave2 = 25.67349073410403548
diff = +0.00000000000000000
ave1 = 25.85428135154362650
ave2 = 25.85428135154361939
diff = +0.00000000000000711
ave1 = 25.78256482459444499
ave2 = 25.78256482459445920
diff = -0.00000000000001421
ave1 = 25.74491985400320360
ave2 = 25.74491985400321425
diff = -0.00000000000001066
ave1 = 25.62551834231759074
ave2 = 25.62551834231758363
diff = +0.00000000000000711