ダブル整数
ダブル整数とは、2セル分を用いて表現される整数のことである。これは、変数の型のようなものではなくて、数値のスタック上への表現の型、といってよい。下の桁を先に、大きい方の桁を後に置く(ある意味、リトルエンディアン)。そうすることで、理論上、2セルビットの範囲(64ビットなら128ビット)の数値が扱えるようになるわけである。1セルの範囲で表せる数値をダブル整数で表現するとすれば、例えば、
1234は
1234 0
と置くことで表現され、
−1234なら、
-1234 -1
と置けば良い。
組み込みマシンのような8ビットや、16ビットの小さなセル単位でしか利用できない窮屈な環境では、今もダブル整数を一般的に使用する意味はあるが、32ビット以上のPC上では、ほとんど使用価値がない。そのため、現在では、ダブル整数一般を扱う規格はオプショナルとされていて、必らずしもすべてのForthに要請されているわけではない。
しかし、掛け算では、掛け合わせられる数値が1セル以内でも、掛けてしまうと大きくなりすぎてはみ出してしまう可能性もある。このような場合には、結果をダブル整数の範囲まで許せば、オーバーフローの危険が減る。
また、計算の途中で数値が大きくなる可能性があるが、その後の割り算などで結局最後は1セル内に収まってしまうような場合、途中の数値範囲に余裕がある方が、結果の信頼性が上がる。
そこで、forth標準規格内には、一部にダブル整数を許すべきことになっている演算が定められている。
掛け算を含むもの
M*
これは、整数の掛け算であるが、結果はダブル整数で出力される。
M* ( n1 n2 -- d ) \ 整数掛け算。結果はダブル整数。
スタック効果コメントではダブル整数はdと一文字で表すが、これは実際には、二つのセルを占めている。
UM*
これは、符号なし(全て正と見なす)の乗法演算(掛け算)である。二つの入力値は符号なし数とみなされ、掛け算した結果は、符号なしダブル整数で表現される。
UM* ( u1 u2 -- ud )
*/
これは複合演算である。結果は1セルのシングル整数であるが、途中結果はダブル整数まで可能であることが規格として要求されている。
*/ ( n1 n2 n3 -- n ) \ (n1*n2)/n3 を計算する。n1*n2の値がダブル整数にわたる大きな数でも良い。余りは捨てる。
*/MOD
上と同じ複合計算だが、余りも出力される。
*/MOD ( n1 n2 n3 -- r q ) \ (n1*n2)/n3を計算する。qが商、rが余り。
特別な割り算
割られる数(dividend)としてタブル整数をとる割り算がいくつか定義されている。
SM/REM
SM/REM ( d n -- r q )
これは整数割り算で、余りと商を出力し、結果はシンメトリック商となる。シンメトリック商は、割られる数か割る数のどちらか一方だけが負の数であるとき、商の結果としては0に近い方(絶対値を小さめに)をとるという手順で得られる。Mops内での通常の割り算もシンメトリックである。スタックコメントの入力のdはダブル整数なので、入力値は3セル分ある。その他は1セル整数で、rは余り、qは商、である。商が大きすぎて1セル内に収まらないような結果になるときはエラーになる(iMopsでは例外を投げてクラッシュするので注意)。
UM/MOD
UM/MOD ( ud u -- r q )
これも整数割り算で、余りと商を出力するが、すべて符号なし整数(正数)として計算する。スタックコメントのudはいわばダブル正数で2セル分の符号なし整数を意味する。その他は上と同じである。
FM/MOD
FM/MOD ( d n -- r q )
整数の割り算であるが、結果がフロアード商となる。フロアード商は、余りの数がいつも割る数(分母)と同じ符号(か0)になるように商が選ばれる。
次
最終更新:2019年12月13日 22:34