【小技】算術演算子の順序
【小技】算術演算子の順序
ランゲージリファレンス > 演算子の項でも説明されているように,4Dの演算子には,優先順位があります。
ご存知のように『4Dの優先順位は厳密に左から右で,代数的順序は採用されていません』。
ところで,4Dのプログラミング言語は,インタープリターモードでも,コンパイルモードでも実行することができます。
コンパイラは,ソースコードを解析し,最終的にアセンブリ言語を出力するのが役割です。
https://ja.wikipedia.org/wiki/コンパイラ
ですから,コンパイルモードの場合,演算子の優先順位は,ソースコードを解析する部分(両モードに共通)だけでなく,コンパイラがアセンブリ言語を出力する部分の振る舞いによっても左右されます。
たとえば,
2+2^3
という式は,
インタープリターモードで64, コンパイルモードで10を返します。
つまり,コンパイラが「2+(2^3)」に相当するアセンブリ言語を出力しているということです。
『厳密に左から右』に評価されないということで,これはドキュメントに記述された言語仕様どおりではなく,コンパイラの『バグ』ともいえる例ですが,この振る舞いは4Dコンパイラの最初期からみられる振る舞いであり,変更すれば,他の演算子の評価に深刻な影響が出ることが容易に予想されるため,『コンパイラの仕様』とされています。
前述したように,『ソースコードを解析する』部分は問題ないので,カッコを付して演算子の優先順位を明示的にすれば,どちらのモードでも同じ振る舞いになります。
ご存知のように『4Dの優先順位は厳密に左から右で,代数的順序は採用されていません』。
ところで,4Dのプログラミング言語は,インタープリターモードでも,コンパイルモードでも実行することができます。
コンパイラは,ソースコードを解析し,最終的にアセンブリ言語を出力するのが役割です。
https://ja.wikipedia.org/wiki/コンパイラ
ですから,コンパイルモードの場合,演算子の優先順位は,ソースコードを解析する部分(両モードに共通)だけでなく,コンパイラがアセンブリ言語を出力する部分の振る舞いによっても左右されます。
たとえば,
2+2^3
という式は,
インタープリターモードで64, コンパイルモードで10を返します。
つまり,コンパイラが「2+(2^3)」に相当するアセンブリ言語を出力しているということです。
『厳密に左から右』に評価されないということで,これはドキュメントに記述された言語仕様どおりではなく,コンパイラの『バグ』ともいえる例ですが,この振る舞いは4Dコンパイラの最初期からみられる振る舞いであり,変更すれば,他の演算子の評価に深刻な影響が出ることが容易に予想されるため,『コンパイラの仕様』とされています。
前述したように,『ソースコードを解析する』部分は問題ないので,カッコを付して演算子の優先順位を明示的にすれば,どちらのモードでも同じ振る舞いになります。
miyako- 投稿数 : 487
登録日 : 2016/07/05
Re: 【小技】算術演算子の順序
C_LONGINT($b;$d)
C_REAL($a;$c)
$a:=2
$b:=MAXLONG
$c:=0.5
$d:=$a*$b/$c
ALERT(String($d))
『イ』-4
『コ』-2147483648
これも,カッコを付けることで回避できる現象・・・かと思ったのですが,そうではありませんでした。
どちらにしても,$dに入る値がLONGINTのオーバーフローですので,不適切な例ですね。
計算順によって,オーバーフローが起きたり起きなかったりする$a;$b;$cの例にするべきでした。
C_REAL($a;$c)
$a:=2
$b:=MAXLONG
$c:=0.5
$d:=$a*$b/$c
ALERT(String($d))
『イ』-4
『コ』-2147483648
これも,カッコを付けることで回避できる現象・・・かと思ったのですが,そうではありませんでした。
どちらにしても,$dに入る値がLONGINTのオーバーフローですので,不適切な例ですね。
計算順によって,オーバーフローが起きたり起きなかったりする$a;$b;$cの例にするべきでした。
miyako- 投稿数 : 487
登録日 : 2016/07/05
Permissions in this forum:
返信投稿: 不可