0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

FORTH ベーシックマスター Lev 17 ー 浮動小数点演算と f 系ワード

Last updated at Posted at 2025-12-12

FORTHはもともと「整数とスタック」を中心にした極めて単純な構造を持つ言語である。しかし科学技術計算や物理シミュレーションなど、実数を扱う場面では整数だけでは不十分だ。そこで登場するのが、gforth における 浮動小数点演算(floating-point arithmetic) である。本章では、FORTH独自の「浮動スタック(f-stack)」の仕組みを理解し、f+, f-, f*, f/ などの基本演算から、平方根・指数・三角関数までを学ぶ。

gforthにおける浮動小数点の基本構造

整数演算とは異なり、浮動小数点演算は 浮動小数点スタック(f-stack) を使って処理される。これにより、整数スタックと混在しても衝突せず、安全に計算できる。

浮動小数点数として解釈されるためには、数値に E (指数) が含まれている必要がある。 1.23E 1E 0.e これらは浮動小数点スタックに積まれる。

各スタックは独立しており、F@, F!, S>F, F>S などのワードを使って整数スタックと浮動スタックの間でデータを移動する。

基本ワードと操作例

代表的なf系ワードを以下にまとめる。

操作 ワード 意味 スタック効果 (f-stack)
加算 f+ 浮動値を加算 ( f1 f2 -- f3 )
減算 f- f1 − f2 ( f1 f2 -- f3 )
乗算 f* f1 × f2 ( f1 f2 -- f3 )
除算 f/ f1 ÷ f2 ( f1 f2 -- f3 )
平方根 fsqrt √f ( f -- f' )
指数 fexp e^f ( f -- f' )
対数 fln ln(f) ( f -- f' )
正弦 fsin sin(f) ( f -- f' )
余弦 fcos cos(f) ( f -- f' )
代入・取得 F!, F@ メモリへ格納・取得 ( f addr -- ) / ( addr -- f )

整数⇔浮動変換のための橋渡しワード:

ワード 説明 スタック効果
S>F 整数を浮動小数に変換 ( n -- f )
F>S 浮動を整数に変換 ( f -- n )
F. 浮動数を表示 ( f -- )

浮動リテラルの入力

gforthでは、数値の後ろに小数点を付けると自動的に浮動数とみなされる:

1.23e2 f.   \ → 123.0
3.14159e f.  \ → 3.14159

ただし整数と区別するため、末尾に指数表記(e)を必ず付ける。

fスタックの挙動を観察する

浮動スタックの状態を確認するには .S ではなく F.S を使う。

1e 2e f+ f.s
出力
<1> 3.0000000000E0

これは、整数スタックとは別に fスタックが存在していることを示している。整数スタックを表示する.Sとは完全に独立している点に注意。

例題1:円の面積を求める

半径を入力し、円の面積(πr²)を計算する。

3.1415926535e FCONSTANT PI

\ 円の半径から面積を求める
: AREA ( f: r -- f: area )
   fdup f* PI f* ;

\ 半径5の円の面積
5e AREA f.    \ → 78.5398163375 

例題2:指数・対数の計算

自然対数と指数関数を組み合わせて確認してみよう。

1.0e fln f.      \ → 0.
2.0e fexp f.     \ → 7.38905609893065

また、fexp fln の組み合わせで恒等性を確認できる:

3.5e fln fexp f. \ → 3.5

これにより、FORTHがIEEE準拠の浮動演算を正しく実装していることがわかる。

例題3:三角関数

fsin, fcos, ftan などのワードはラジアン単位で動作する。
例えば 90° = π/2 を代入して確認する。

3.1415926535e FCONSTANT PI
PI 2e f/ fsin f.   \ → 1.
PI 2e f/ fcos f.   \ → 0.0000000000448965921697616

角度を度単位で扱いたい場合は、事前にラジアン変換する:

度 × π / 180 = ラジアン
: DEG>RAD ( f: deg -- f: rad )
   PI 180e f/ f* ;

メモリとのやり取り:f@ と f!

浮動変数を使うには、CREATEf!f@を組み合わせる。

CREATE TEMP 1 FLOATS ALLOT  \ 浮動1セル分のメモリを確保
37.5e TEMP f!              \ 書き込み
TEMP f@ f.                  \ → 37.5

ここで FLOATS は、環境依存の浮動数サイズを正しく確保するための定数である(通常は8バイト)。

整数との相互変換

整数で受け取った値を浮動計算に使いたい場合、S>Fを使う。

10 S>F 3.0e f/ f.   \ → 3.33333

逆に、浮動演算の結果を整数に戻すには F>S

2.9e F>S .   \ → 2  (小数部切り捨て)

応用例:単利計算プログラム

利率 r(%/年)、期間 t(年)、元本 p から単利を求める。

: INTEREST ( f: p r t -- f: i )
   f* f* 100e f/ ;   \ p * r * t / 100

10000e 3.5e 5e INTEREST f.   \ → 1750.

浮動演算なら、金利・時間・温度・面積・速度など、連続的な量をそのまま扱える。

応用例:ニュートン法による平方根近似

整数では誤差が生じる近似計算も、浮動数なら滑らかに実装できる。

: FSQRT-N ( f: x -- f: root )
    FDUP 0E F<= IF
        FDROP 0E EXIT
    THEN
    FDUP FSQRT \ 初期値
    10 0 DO
        FOVER FOVER F/ F+ 2E F/
    LOOP FNIP
;
実行
9E FSQRT-N F. \ → 3.
2E FSQRT-N F. \ →1.41421356237309
0E FSQRT-N F. \ → 0.

このプログラムは、$\sqrt{N}$ を見つけるために、以下の有名な漸化式(反復計算)を使用している。

$x_{n+1} = \frac{1}{2} \cdot \left( x_n + \frac{N}{x_n} \right)$

fスタックと通常スタックの同時利用

整数でループ回数を管理し、fスタックで計算を行う例:

: SUM-UP ( n -- f: sum )
    0E           \ 初期値
    1 + 1 DO
        I S>F F+ \ fスタック上で計算
    LOOP
    F>S ;        \ 通常スタックに戻す

整数スタックのIとfスタックが明確に分離されていることがわかる。この二重構造はFORTHならではの柔軟な特徴である。

練習課題

  1. 半径を入力して円周長(2πr)を求めるワードを作成せよ。
  2. fsinfcosを用いて、任意角度のサイン・コサイン表を出力するプログラムを書け。
  3. 台形法で関数 f(x)=x^2 を 0〜1 の範囲で積分し、結果を小数で表示せよ。
  4. f@f! を使って温度記録を保持・更新するプログラムを作成せよ。
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?