【仕様】64ビット版における0.5の「丸め」処理について
2 posters
【仕様】64ビット版における0.5の「丸め」処理について
15R4/v16以降,64ビット版のコンパイラーは,実数の「丸め」処理に対してIntelのCPU命令を出力するようになりました。
IntelのCPU命令は,いわゆる「四捨五入」とは違い,「x.5」という値を交互に切り上げたり切り下げたります。
例:
0.5 => 0
1.5 => 2
2.5 => 2
3.5 => 4
これは,値を加算したときに発生する誤差を抑えるための処置です。
上述の例で言えば,「丸め」処理をしてもしなくても,結果は「8」となります。対照的に,四捨五入では合計値が1+2+3+4=10となります。
これは,IntelのCPU命令の仕様であり,したがってコンパイルモード特有の動作ですが,64ビット版の4Dでは,両モードの動きを揃えるため,インタープリターモードであっても同じ方法で「丸め」処理が実行されます。なお,32ビット版では,互換性に配慮し,両モードともにいわゆる「四捨五入」処理が実行されます。
Intel CPUの「丸め」処理(最近接偶数丸め)は「四捨五入」ではない,という点に注意してください。特にクライアントは32ビット版,サーバーは64ビット版といった環境でRound() をコールしている場合,処理を実行するマシンによって結果に違いが出ることになります。
IntelのCPU命令は,いわゆる「四捨五入」とは違い,「x.5」という値を交互に切り上げたり切り下げたります。
例:
0.5 => 0
1.5 => 2
2.5 => 2
3.5 => 4
これは,値を加算したときに発生する誤差を抑えるための処置です。
上述の例で言えば,「丸め」処理をしてもしなくても,結果は「8」となります。対照的に,四捨五入では合計値が1+2+3+4=10となります。
これは,IntelのCPU命令の仕様であり,したがってコンパイルモード特有の動作ですが,64ビット版の4Dでは,両モードの動きを揃えるため,インタープリターモードであっても同じ方法で「丸め」処理が実行されます。なお,32ビット版では,互換性に配慮し,両モードともにいわゆる「四捨五入」処理が実行されます。
Intel CPUの「丸め」処理(最近接偶数丸め)は「四捨五入」ではない,という点に注意してください。特にクライアントは32ビット版,サーバーは64ビット版といった環境でRound() をコールしている場合,処理を実行するマシンによって結果に違いが出ることになります。
miyako- 投稿数 : 468
登録日 : 2016/07/05
Re: 【仕様】64ビット版における0.5の「丸め」処理について
下記の様な処理を書いてコンパイルモードで動かしてみたのですが、結果が四捨五入になります。
上記の説明はどの様な場合のものなのでしょうか?
$r1:=Round(0.5;0)
$r2:=Round(1.5;0)
$r3:=Round(2.5;0)
$r4:=Round(3.5;0)
ALERT(New collection($r1;$r2;$r3;$r4).join("\r"))
上記の説明はどの様な場合のものなのでしょうか?
$r1:=Round(0.5;0)
$r2:=Round(1.5;0)
$r3:=Round(2.5;0)
$r4:=Round(3.5;0)
ALERT(New collection($r1;$r2;$r3;$r4).join("\r"))
hosaka- 投稿数 : 241
登録日 : 2016/07/04
所在地 : 大阪
Re: 【仕様】64ビット版における0.5の「丸め」処理について
実数を整数に「キャスト」した場合に現象が適用されます。
例
$r1:=0.5
$r2:=1.5
$r3:=2.5
$r4:=3.5
C_LONGINT($int)
$c:=New collection
For each ($int;New collection($r1;$r2;$r3;$r4))
$c.push($int)
End for each
ALERT($c.join("\r"))
例
$r1:=0.5
$r2:=1.5
$r3:=2.5
$r4:=3.5
C_LONGINT($int)
$c:=New collection
For each ($int;New collection($r1;$r2;$r3;$r4))
$c.push($int)
End for each
ALERT($c.join("\r"))
miyako- 投稿数 : 468
登録日 : 2016/07/05
Re: 【仕様】64ビット版における0.5の「丸め」処理について
こう書かれていたのでてっきりRound()かと思ってました。今まで通りRound()とint()は四捨五入でいいんですね。miyako wrote:
Intel CPUの「丸め」処理(最近接偶数丸め)は「四捨五入」ではない,という点に注意してください。特にクライアントは32ビット版,サーバーは64ビット版といった環境でRound() をコールしている場合,処理を実行するマシンによって結果に違いが出ることになります。
ところでサンプルをmacで動かしたのですが、alert表示直後は0のみ表示されて、その後2,2,4が遅れて表示されます。私の環境だけでしょうか。
hosaka- 投稿数 : 241
登録日 : 2016/07/04
所在地 : 大阪
Permissions in this forum:
返信投稿: 不可
|
|