小数用のワードセットは、対応する整数用ワードの名前の前にFを付けただけのものが多い。
オプションであるので、商品forthかgForthでなければ、規格に含まれた全てのワードが完備されていることは期待できない。Mopsもかなりズレがある。基本的に必要と思われるものについてのみ説明する。
なお、PowerMopsとiMopsでは、浮動小数点数は標準でダブル精度(64ビット)である。

FVARIABLE FVALUE FCONSTANT


浮動小数点数(以下、小数と略す)は、1セル幅が整数と異なる場合もある。そのために、小数用の変数を定義する方法がある。もっとも基本的なものは、FVARIABLEである。このワードと伴に変数名を宣言する。VARIABLEと基本的に同じである。
FVARIABLE   ( “<spaces>name” -- )  \ 小数変数を定義する
例えば、
FVARIABLE FV1
とすれば、小数変数FV1が定義される。FV1の動作は、そのデータ域のメモリーアドレスをスタックに置くのみである。この点もVARIABLEと同じである。
FV1  ( -- addr )

実は、小数用変数といっても、実際には小数セル幅のデータ域でしかなく、整数用変数と本質的な違いはない。小数を格納し、または取り出すためのワードが違いを生みだしているのである。

FVARIABLEの小数の値を出し入れするのはF@F!である。もちろん、F@は取り出し、F!は格納である。
F@  ( S: addr -- )  ( F: -- r )
F!  ( S: addr -- )  ( F: r -- )
小数の値は小数スタックに置かれる。値は、小数スタックと遣り取りされるのである。
小数ワードライブラリーがロードされていれば、数字は、小数点を付けるだけで小数と解釈され、小数スタックに置かれる。
0.1 FV1 F!  \ FVARIABLE FV1に0.1を格納
FV1 F@      \ F: -- 0.1 取り出し

VALUEの小数版がFVALUEである。その名前を値と同一視でき、"TO"か"->"で値を格納する。宣言時に初期値が必要なこともVALUEと同じである。
0.1 FVALUE FVL1  \ 初期値は0.1
3.14159265 -> FVL1  \ πの値を格納
FVL1  \ 値は小数スタックにコピーされる

CONSTANTの小数版はFCONSTANTである。これはFVALUEと同じ構文で宣言し、ほとんど同じように利用することができるが、TOや->で値を格納することができない。
3.14159265358979 FCONSTANT PI

計算 スタック操作


四則演算は、通常の記号の前にFを付ける。
F+  ( F: r1 r2 -- r1+r2 )
F-  ( F: r1 r2 -- r1-r2 )
F*  ( F: r1 r2 -- r1*r2 )
F/  ( F: r1 r2 -- r1/r2 )
特に説明は不要だろう。

小数の符号を変えるFNEGATE、絶対値を取るFABSも計算上有用だろう。
FNEGATE  ( F: r -- -r )
FABS  ( F: r -- |r| )
また、2つの小数のより小さくない方の値を取るFMAX、より大きくない方の値を取るFMINもある。
FMAX ( F: r1 r2 -- r )  \ rは、r1、r2のうち、より小さくない方。
FMIN ( F: r1 r2 -- r )  \ rはr1、r2のうち、より大きくない方。

スタック操作ワードはあまり多くない。実際、小数スタックは、整数スタックと比べて負担が軽いため、操作する必要性があまり生じない。これらも、通常のものの冒頭にFが付いたものになっている。
FDROP  ( F: r -- )
FSWAP  ( F: r1 r2 -- r2 r1 )
FDUP   ( F: r -- r r )
FOVER  ( F: r1 r2 -- r1 r2 r1 )
FROT   ( F: r1 r2 r3 -- r2 r3 r1 )

なお、forth標準にはないが、iMopsには次のワードも定義してある。
FDOWN ( F: r1 r2 r3 -- r3 r1 r2 )
-FROT \ FDOWNと同義
FTUCK ( F: r1 r2 -- r2 r1 r2 ) 
F2SWAP  ( F: r1 r2 r3 r4 -- r3 r4 r1 r2 )

比較判定


値の大小比較ワードも、頭にFを付ければよい。しかし、標準規格にある小数の比較演算子は少ない。
真偽のフラグは整数スタックに積まれることの注意しなければならない。しかし、比較を連続する場合にはむしろそのせいでコードは書きやすくなる。
forth標準規格にあるのは以下のものだけである。
F<   ( F: r1 r2 -- ) ( S: -- b )  \ r1がr2より小さいときにはtrue(=-1)、そうでなければfalse(=0)
F0<  ( F: r -- ) ( S: -- b )  \ rが0より小さいときはtrue、そうでなければfalse
F0=  ( F: r -- ) ( S: -- b )  \ rが0のときはtrue、そうでなければfalse
Mopsでは以下のような拡張ワードが定義されている。ただし、iMopsでは0と比較するものは、forth規格のものも含めて、定義されていない。
F>   ( F: r1 r2 -- ) ( S: -- b ) \ r1がr2より大きいときにはtrue(=-1)、そうでなければfalse(=0)
F<=  ( F: r1 r2 -- ) ( S: -- b ) \ r1がr2より小さいが互いに等しいときはtrue(=-1)、そうでなければfalse(=0)
F>=  ( F: r1 r2 -- ) ( S: -- b ) \ r1がr2より大きいか互いに等しいときにはtrue(=-1)、そうでなければfalse(=0)
F=   ( F: r1 r2 -- ) ( S: -- b ) \ r1とr2が互いに等しいときにはtrue(=-1)、そうでなければfalse(=0)
F<>  ( F: r1 r2 -- ) ( S: -- b ) \ r1とr2が異なるときにはtrue(=-1)、そうでなければfalse(=0)
F0<= ( F: r -- ) ( S: -- b ) \ rが0より小さいときはtrue、そうでなければfalse
F0>  ( F: r -- ) ( S: -- b ) \ rが0より小さいときはtrue、そうでなければfalse
F0>= ( F: r -- ) ( S: -- b ) \ rが0のときはtrue、そうでなければfalse
F0<> ( F: r -- ) ( S: -- b ) \ rが0のときはtrue、そうでなければfalse

整数との変換


整数を小数に、あるいは逆に、小数を整数に、変換するためのワードもある。整数は浮動小数点数としての整数に変換されるだけであるが、小数を整数に変換するときには、小数点以下は切り捨てられる。Forth標準では、整数側はダブルセル整数であることが予定されている。浮動小数点数の方が、大きな桁数を表現できるからであろう。
D>F ( S: d -- ) ( F: -- r )  \ ダブルセル整数を浮動小数点数に変換
F>D ( S: -- d ) ( F: r -- )  \ 小数をダブルセル整数に変換。端数は切り捨て。
ただし、iMopsではこれらは定義されていない。代わりに、forth標準ではないが、通常の、つまりセル1つ分の整数と小数の間で変換するワードが定義されている。
S>F ( S: n -- ) ( F: -- r )  \ 整数を浮動小数点数に変換
F>S ( S: -- n ) ( F: r --  ) \ 小数を整数に変換。端数は切り捨て。
PowerMopsではダブル・シングル両方とも定義されている。

ライブラリ関数


浮動小数点数ワードセットには、数学上の関数が含まれている。初等解析関数にあたるものである。関数名の冒頭にFを付けた名前のものが多い。
Mopsでは、これらの関数については、概ね標準Cライブラリの関数を呼び出すことで対応している。
Forth標準規格で定められているものは次の通りである。
FCOS   ( F: r -- r' )     \ 三角関数の余弦(コサイン)cos()
FSIN   ( F: r -- r' )     \ 三角関数の正弦(サイン)sin()
FTAN   ( F: r -- r' )     \ 三角関数の正接(タンジェント)tan()
FACOS  ( F: r -- r' )     \ 逆三角関数、arccos()
FASIN  ( F: r -- r' )     \ 逆三角関数、arcsin()
FATAN  ( F: r -- r' )     \ 逆三角関数、arctan()
FATAN2 ( F: r1 r2 -- r )  \ rは-πからπの範囲で、そのtangentの値がr1/r2になる角
FCOSH  ( F: r -- r' )     \ 双曲関数、cosh()
FSINH  ( F: r -- r' )     \ 双曲関数、 sinh()
FTANH  ( F: r -- r' )     \ 双曲関数、tanh()
FACOSH ( F: r -- r' )     \ 逆双曲関数、arccosh()
FASINH ( F: r -- r' )     \ 逆双曲関数、arcsinh()
FATANH ( F: r -- r' )     \ 逆双曲関数、arctanh()
FLOG   ( F: r -- r' )     \ 常用対数関数(底が10):rは10のr'乗
FALOG  ( F: r -- r' )     \ FLOGの逆関数。r'は10のr乗
FLN    ( F: r -- r' )     \ 自然対数関数 ln()
FLNP1  ( F: r -- r' )     \ r'は(r+1)の自然対数
FEXP   ( F: r -- r' )     \ 指数関数exp()
FEXPM1 ( F: r -- r ' )    \ r'はeのr乗から1を引いた値
F**    ( F: r1 r2 -- r  ) \ rはr1のr2乗
FSQRT  ( F: r -- r'  )    \ r'はrの平方根(ルート)
なお、iMopsではFALOGは定義されていない。F**を用いれば定義は容易であるが。

ダブル精度、シングル精度


浮動小数点数を記述する規格には、総体を32ビットで表現するシングル精度と、総体を64ビットで表現するダブル精度がある。(この他に、X86のFPU(X87ともいう)では80ビット精度の浮動小数点数が用いられているが、これは措く。)
通常の小数は、各forthシステム毎に規格が異なる可能性はあるものの、当のシステムの標準にしたがった処理を前提としたワードで処理される。
しかし、他方で、外部ライブラリとの整合性の問題などから、シングル精度かダブル精度かを特定して小数を処理する必要が出てくることもある。そのためのワードもforth規格では規定されている。

DF! DF@

ダブル精度であることを特定して、小数をメモリーに格納、あるいはメモリーから取り出すワードが、DF!DF@である。
DF!  ( S: addr -- )  ( F: r -- ) \ 小数スタック上の小数をダブル精度の小数として、addrの位置に格納
DF@  ( S: addr -- )  ( F: -- r ) \ addrの位置に格納されたダブル精度小数を、小数スタック上に取り出し
小数スタックがダブル精度と異なる場合には、やり取りの間に規格が変更される。メモリー領域は64ビット(8バイト)なければならず、適切にアラインされていなければならない(アドレスが8の倍数ということ)。
Mopsではデフォルトでダブル精度であるから、F!, F@と同義である。これらはiMopsでは定義されていない。

SF! SF@

これらは、シングル精度であることを特定して、小数をメモリ上に格納、あるいはメモリーから取り出す。
DF!  ( S: addr -- )  ( F: r -- ) \ 小数スタック上の小数をシングル精度の小数として、addrの位置に格納
DF@  ( S: addr -- )  ( F: -- r ) \ addrの位置に格納されたシングル精度小数を、小数スタック上に取り出し
これらの場合も、小数スタックがシングル精度ではない場合には、やり取りの際、相互に規格変換が行われる。シングル精度小数を格納するメモリーのアラインメントは32ビット(4バイト)である。

なお、シングル精度の小数をスタック経由で外部関数に渡す必要がある可能性を考えて、iMopsではスタック上で、ダブル精度とシングル精度の間の変換を行うワード、SF>F、F>SFを定義している。これらは、forth標準規格にはない。
F>SF  ( F: r -- r' ) \ rはダブル精度、r'はシングル精度の対応する小数。近い値に切り詰める(四捨五入)。
SF>F  ( F: r -- r' ) \ rはシングル精度、r'はダブル精度の対応する小数。
小数スタック上ではダブル精度が前提とされているので、シングル精度ではスタック表示がおかしくなるので注意を要する。

F. FS. FE.


浮動小数点数をコンソールに印字するワードが三種類ある。
どれも小数スタック上の値を1つ消費して、その値を表示するが、表記方法が異なる。
F. は、小数点を用いて10進桁表示する。いわゆる普通にいう小数の表記である。1.234とか、567.89のような形式である。
FS. は、いわゆる科学記法で印字する。1.23E4とか、2.3E-6のような表記法である。
FE.は、エンジニアリング記法と呼ばれる表記法で表示する。規格には、有効数字は1.0以上1000.0未満であって、10の冪は3の倍数であるもの、とされている。正直、意味がよくわからない。多分、3.1415924なら3.142e0、746545834なら746.5e6、56708なら56.7e3、という感じだろうか?

iMopsでも定義しているが、NextStepのコア関数の規格のままなので、キッチリforth規格には合っていない。例えば、F. FE.では、整数部分の桁数が多いと3桁毎にコンマを打つし、FE.の小数点以下は、小数第4位を四捨五入して第3位までに切り詰めて表示する。
一種のユーティリティーで、Mopsではプログラムに使うことはないワードである。



最終更新:2013年09月28日 15:39