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 18 ー ダブル整数とビット演算

0
Last updated at Posted at 2025-12-13

FORTHは「スタックにすべてを積む」言語である。そのため、他言語のように型を区別することは少ないが、数値の桁あふれ(overflow)ビット単位の操作 を扱うには、内部表現を意識する必要がある。

本章では、gforthで扱うダブル整数(double-cell integer)ビット演算を学び、整数演算をより低レベルで制御する方法を身につける。

数値変換

FOTHのテキストインタープリタは、入力された文字列を数値に変換しようとする。

表記 説明
<digit><digit>* 123 正の整数
-<digit><digit>* -123 負の整数
<digit><digit>*.<digit>* 123.45 正のダブル整数(12345)
-<digit><digit>*.<digit>* -123.45 負のダブル整数(-12345)
{+ -}<decimal digit>{.}<decimal digit>*{e E}{+ -}<decimal digit><decimal digit>* 1e 1e0 1.e 1.e0 +1e+0 浮動小数点
接頭辞 説明
& &123 10進数
# #123 10進数
% %1011 2進数
$ $1B 16進数
0x 0x1B 16進数

BASE(基数)

BASE という変数で、入力時の数値基数を変更できる。

DECIMAL 123 456 . .  \ → 123 456
HEX 1A 7B . .        \ → 1A 7B
BASE @ DECIMAL .     \ → 16 (16進数)

シングルセルとダブルセル

gforthの整数は通常1セル(cell)=32bitまたは64bit(環境依存)である。これを倍のサイズ(2セル)で扱う整数が「ダブル整数」である。

通常、#123. の様に、頭に#をつけ、最後に.をつける。123. の様に書くとgforthがワーニングを表示する。

#123.     \ ダブル整数
123.      \ ダブル整数 → warning: '123.' is a double-cell integer
#123      \ シングル整数

スタック上の構造

低位・高位の2セルで保存される。( lower upper )

12345.123 \ → 12345123 0

ダブル整数を扱うワードは D+, D-, D*, D/ など、頭に D が付いている。

基本操作ワード一覧

ワード スタック効果 説明
2@ ( addr -- x1 x2 ) メモリから2セル読み出し
2! ( x1 x2 addr -- ) メモリに2セル書き込み
2DROP ( x1 x2 -- ) ダブル整数を削除
2DUP ( x1 x2 -- x1 x2 x1 x2 ) ダブル整数を複製
D. ( d -- ) ダブル整数を表示
D+ ( d1 d2 -- d3 ) ダブル整数の加算
D- ( d1 d2 -- d3 ) ダブル整数の減算
DNEGATE ( d -- -d ) 符号反転
DABS ( d -- ud ) 符号なしダブル整数
DMIN ( d1 d2 -- d ) ダブル整数の最小値
DMAX ( d1 d2 -- d ) ダブル整数の最大値
D>S ( d -- n ) ダブル整数をシングル整数に変換
S>D ( n -- d ) シングル整数をダブルに変換

ダブル整数を扱う例

例:大きな数の加算
1234567890000000000 9876543210000000000 + .     \ → -7335632973709551616 桁あふれ
1234567890000000000. 9876543210000000000. D+ D. \ → 11111111100000000000 

通常の整数では桁あふれする範囲も、D+ により安全に扱える。

メモリへの格納と読み出し

2@2! により、メモリ上にダブル整数を記録できる。

CREATE BIGNUM 2 CELLS ALLOT
12345678901234567890 1 BIGNUM 2!  ok
BIGNUM 2@ D. \ → 30792422974944119506

ビット演算ワードの基礎

ビット単位での操作は、ハードウェア制御・暗号・圧縮などに不可欠である。特にセンサーとの通信や計算能力の低い機器、使用できるメモリが限られている場合に活用される。

ワード スタック効果 内容
AND ( n1 n2 -- n3 ) ビットごとのAND
OR ( n1 n2 -- n3 ) ビットごとのOR
XOR ( n1 n2 -- n3 ) ビットごとのXOR
INVERT ( n1 -- n2 ) ビット反転(NOT)
LSHIFT ( x u -- x<<u ) 左シフト
RSHIFT ( x u -- x>>u ) 右シフト
1+, 1- ( n -- n±1 ) 加減算(1単位)

ビットシフト

例:2のべき乗の掛け算や割り算
10 1 LSHIFT .    \ 10 * 2^1 = 20
10 3 LSHIFT .    \ 10 * 2^3 = 80
80 3 RSHIFT .    \ 80 / 2^3 = 10
例:1バイトの値から上位4bit/下位4bitを取り出す
HEX
AB CONSTANT BYTE   \ 0xAB = 1010 1011b
BYTE 4 RSHIFT .    \ → A(上位4bit) A 
BYTE 0F AND .      \ → B(下位4bit) B 
DECIMAL

例題:偶数・奇数判定

: EVEN? ( n -- flag )
   1 AND 0= ;

5 EVEN? .   \ → 0(奇数)
8 EVEN? .   \ → -1(偶数)

ビットANDで最下位ビット(LSB)を確認する簡単な例。

例題:ビットマスクによるフラグ管理

1 CONSTANT FLAG-A
2 CONSTANT FLAG-B
4 CONSTANT FLAG-C
VARIABLE FLAGS

\ AとCをONにする
FLAG-A FLAG-C OR FLAGS !

\ Bフラグが立っているか確認
FLAGS @ FLAG-B AND 0<> .

ビットごとのORやANDを使うことで、複数の状態(ON/OFF)を1つの整数で管理できる。

## 例題:チェックサムの作成(単純XOR法)

: CHECKSUM ( addr len -- n )
   0 SWAP 0 DO
      OVER I + C@ XOR
   LOOP
   NIP ;

この簡易的なチェックサム関数は、各バイトを順にXORして1バイトの結果にまとめる。低レベル通信やファイル検査などで使われる基本構造である。

例題:32bitチェックサム

: D-CHECK ( addr len -- dsum )
   0 0 2SWAP 0 DO
      OVER I + C@ S>D D+    \ バイトをダブルに加算
   LOOP
   2DROP ;

このように、S>DD+ を組み合わせることで32bitを超える累積和を安全に保持できる。

例題:ビットカウント(セットビット数)

: BIT-COUNT ( n -- u )
   0 SWAP
   BEGIN
      DUP 0= IF DROP EXIT THEN
      DUP 1 AND IF SWAP 1+ SWAP THEN
      1 RSHIFT
   AGAIN ;

これは、整数の中に「1」がいくつあるかを数える例。ビット演算がループと結びつく典型的なパターンである。

練習課題

  1. 64bit整数 D+, D* を使って、階乗(factorial)のダブル精度版を作成せよ。
  2. AND, OR, XOR を用いて、4bitの論理演算表を出力せよ。
  3. LSHIFTRSHIFT を組み合わせて、ビット反転を行う関数を実装せよ。
  4. UM* を使って、65535 × 65535 の正確な積を計算せよ。
  5. CHECKSUM を改良し、16bit(ダブルセル)累積チェックを行うよう変更せよ。
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?