R6RS:翻訳:Standard Libraries:11.2 Fixnums
11.2 fixnum
各実装系は閉区間
で w ≥ 24 なる(数学的な)整数の fixnum の範囲を定義しなければならない。実装系の fixnum の範囲内の数学的な整数は実装系で表現可能な正確な整数オブジェクトに対応しなければならない。 fixnum はこの fixnum の範囲にある正確な整数オブジェクトである。
本節では (rnrs arithmetic fixnums (6)) ライブラリについて述べる。このライブラリは fixnum 上の様々な演算を定義する。 fixnum 演算は fixnum の引き数に対して整数演算を行なうが、結果が fixnum でない場合には &implementation-restriction コンディション型の例外を発生させる。
本節では fx、 fx1、 fx2 等を fixnum でなければならない引き数の仮引き数名として使う。
[procedure] (fixnum? obj)
obj が fixnum の範囲に収まる正確な整数オブジェクトであれば #t を返し、そうでなければ #f を返す。
[procedure] (fixnum-width)
[procedure] (least-fixnum)
[procedure] (greatest-fixnum)
これらの手続きはそれぞれ w、 -2^(w - 1)、 2^(w - 1) - 1、すなわち、 fixnum の範囲の幅、最小値最大値を返す。
[procedure] (fx=? fx1 fx2 fx3 ...)
[procedure] (fx>? fx1 fx2 fx3 ...)
[procedure] (fx<? fx1 fx2 fx3 ...)
[procedure] (fx>=? fx1 fx2 fx3 ...)
[procedure] (fx<=? fx1 fx2 fx3 ...)
これらの手続きは引き数が(それぞれ)、等しい場合、単調増加している場合、単調減少している場合、単調減少していない場合、単調増加していない場合に #t を返し、それ以外は #f を返す。
[procedure] (fxzero? fx)
[procedure] (fxpositive? fx)
[procedure] (fxnegative? fx)
[procedure] (fxodd? fx)
[procedure] (fxeven? fx)
これらの数値述語は fixnum の特定の性質を検査して #t か #f を返す。これらの手続きで検査されるのは、数値オブジェクトが 0 であるか、 0 より大きいか、 0 より小さいか、奇数であるか、偶数であるか、である。
[procedure] (fxmax fx1 fx2 ...)
[procedure] (fxmin fx1 fx2 ...)
これらの手続きは引き数の最大値と最小値を返す。
[procedure] (fx+ fx1 fx2)
[procedure] (fx* fx1 fx2)
これらの手続きは引き数の和と積を返し、和と積は fixnum で与えられる。和や積が fixnum でない場合は &implementation-restriction コンディション型の例外が発生する。
[procedure] (fx- fx1 fx2)
[procedure] (fx- fx)
二引き数の場合は差 fx1 - fx2 を返す。差は fixnum で与えられる。
一引き数の場合、引き数の加法の逆元を返し、その整数オブジェクトは fixnum で与えられる。
この手続きの数学的に正しい結果が fixnum でない場合には &assertion コンディション型の例外が発生する。
(fx- (least-fixnum)) &assertion exception
[procedure] (fxdiv-and-mod fx1 fx2)
[procedure] (fxdiv fx1 fx2)
[procedure] (fxmod fx1 fx2)
[procedure] (fxdiv0-and-mod0 fx1 fx2)
[procedure] (fxdiv0 fx1 fx2)
[procedure] (fxmod0 fx1 fx2)
fx2 は 0 であってはならない。これらの手続きは整数論上の整数の除算を実装し、 R6RS:翻訳:R6RS:11.7.3.1 Integer division に規定されている数学演算に対応する結果を返す。
(fxdiv fx1 fx2) ⇒ fx1 div fx2
(fxmod fx1 fx2) ⇒ fx1 mod fx2
(fxdiv-and-mod fx1 fx2)
⇒ fx1 div fx2, fx1 mod fx2
; two return values
(fxdiv0 fx1 fx2) ⇒ fx1 divsb0 fx2
(fxmod0 fx1 fx2) ⇒ fx1 modsb0 fx2
(fxdiv0-and-mod0 fx1 fx2)
⇒ fx1 fx1 divsb0 fx2, fx1 modsb0 fx2
; two return values
[procedure] (fx+/carry fx1 fx2 fx3)
次の計算の結果の fixnum をふたつ返す。
(let* ((s (+ fx1 fx2 fx3))
(s0 (mod0 s (expt 2 (fixnum-width))))
(s1 (div0 s (expt 2 (fixnum-width)))))
(values s0 s1))
[procedure] (fx-/carry fx1 fx2 fx3)
次の計算の結果の fixnum をふたつ返す。
(let* ((d (- fx1 fx2 fx3))
(d0 (mod0 d (expt 2 (fixnum-width))))
(d1 (div0 d (expt 2 (fixnum-width)))))
(values d0 d1))
[procedure] (fx*/carry fx1 fx2 fx3)
次の計算の結果の fixnum をふたつ返す。
(let* ((s (+ (* fx1 fx2) fx3))
(s0 (mod0 s (expt 2 (fixnum-width))))
(s1 (div0 s (expt 2 (fixnum-width)))))
(values s0 s1))
[procedure] (fxnot fx)
mod 2^w と合同な fx の 1 の補数の一意な fixnum を返す。
[procedure] (fxand fx1 ...)
[procedure] (fxior fx1 ...)
[procedure] (fxxor fx1 ...)
これらの手続きは引き数の 2 の補数表現の「論理積」「論理和」「排他的論理和」の fixnum を返す。引き数がひとつしか与えられなかった場合には、その引き数を返す。引き数をひとつも渡さなかった場合は、この演算に対する単位元の fixnum (-1 か 0)を返す。
[procedure] (fxif fx1 fx2 fx3)
引き数の 2 の補数表現のビット単位の「if」の fixnum を返す。すなわち、各ビットについて、 fx1 中で 1 の場合、 fx2 の対応するビットが戻り値で対応する値になり、 0 の場合、 fx3 の対応するビットが戻り値で対応する値になる。これは次の計算の結果の fixnum である。
(fxior (fxand fx1 fx2)
(fxand (fxnot fx1) fx3))
[procedure] (fxbit-count fx)
fx が非負の場合、この手続きは fx の 2 の補数表現の 1 であるビットの個数を返す。負数の場合はつぎ の計算の結果を返す。
(fxnot (fxbit-count (fxnot ei)))
[procedure] (fxlength fx)
fx が正である場合には fx を表すのに必要なビット数を返し、負数である場合には (fxnot fx) を表すのに必要なビット数を返す。これは次の計算の結果の fixnum である。
(do ((result 0 (+ result 1))
(bits (if (fxnegative? fx)
(fxnot fx)
fx)
(fxarithmetic-shift-right bits 1)))
((fxzero? bits)
result))
[procedure] (fxfirst-bit-set fx)
fx の 2 の補数表現で 1 である最下位のビットの添え字を返す。 fx が 0 であった場合には -1 が返る。
(fxfirst-bit-set 0) ⇒ -1 (fxfirst-bit-set 1) ⇒ 0 (fxfirst-bit-set -4) ⇒ 2
[procedure] (fxbit-set? fx1 fx2)
fx2 は非負で (fixnum-width) より小くなければならない。 fxbit-set? 手続きは fx1 の 2 の補数表現における fx2 番目のビットが 1 であれば #t を返し、そうでなければ #f を返す。これは次の計算の結果の fixnum である。
(not
(fxzero?
(fxand fx1
(fxarithmetic-shift-left 1 fx2))))
[procedure] (fxcopy-bit fx1 fx2 fx3)
fx2 は非負で (fixnum-width) より小さくなければならず、 fx3 は 0 か 1 でなければならない。 fxcopy-ibt 手続きは fx1 の fx2 番目のビットを fx3 で取り換えた結果を返す。これは次の計算の結果に等しい。
(let* ((mask (fxarithmetic-shift-left 1 fx2)))
(fxif mask
(fxarithmetic-shift-left fx3 fx2)
fx1))
[procedure] (fxbit-field fx1 fx2 fx3)
fx2 と fx3 は非負で (fixnum-width) より小さくなければならない。さらに、 fx2 は fx3 以下でなければならない。 fxbit-field-procedure は fx2 から(これを含む) fx3 まで(これを含まない)の位置のビットで表される数値を返す。これは次の計算の結果の fixnum である。
(let* ((mask (fxnot
(fxarithmetic-shift-left -1 fx3))))
(fxarithmetic-shift-right (fxand fx1 mask)
fx2))
[procedure] (fxcopy-bit-field fx1 fx2 fx3 fx4)
fx2 と fx3 は非負で (fixnum-width) より小さくなければならない。さらに fx2 は fx3 以下でなければならない。 fxcopy-bit-field 手続きは fx1 の fx2 から(これを含む) fx3 まで(これを含まない)の位置のビットを fx4 の対応するビットで置き換えたものを返す。これは次の計算の結果の fixnum である。
(let* ((to fx1)
(start fx2)
(end fx3)
(from fx4)
(mask1 (fxarithmetic-shift-left -1 start))
(mask2 (fxnot
(fxarithmetic-shift-left -1 end)))
(mask (fxand mask1 mask2)))
(fxif mask
(fxarithmetic-shift-left from start)
to))
[procedure] (fxarithmetic-shift fx1 fx2)
fx2 の絶対値は (fixnum-width) より小さくなければならない。 (floor (* fx1 (expt 2 fx2))) が fixnum であればその fixnum が返り、そうでなければ &implementation-restriction コンディション型の例外が発生する。
[procedure] (fxarithmetic-shift-left fx1 fx2)
[procedure] (fxarithmetic-shift-right fx1 fx2)
fx2 は非負で (fixnum-width) より小さくなければならない。 fxarithmetic-shift-left は fxarithmethic-shift と同様に振る舞い、 (fxarithmethic-shift-right fx1 fx2) は (fxarightmec-shift fx1 (fx- fx2)) と同様に振る舞う。
[procedure] (fxrotate-bit-field fx1 fx2 fx3 fx4)
fx2、 fx3、 fx4 は非負で (fixnum-width) より小さくなければならない。 fx2 は fx3 以下でなければならず、 fx4 は fx3 - fx2 未満でなければならない。 fxrotate-bit-field-procedure は fx1 中の fx2 から(これを含む) fx3 まで(これを含まない)の位置のビットを fx4 ビットだけ上位ビット方向に回転移動させる。これは次の計算の結果である。
(let* ((n fx1)
(start fx2)
(end fx3)
(count fx4)
(width (fx- end start)))
(if (fxpositive? width)
(let* ((count (fxmod count width))
(field0
(fxbit-field n start end))
(field1
(fxarithmetic-shift-left
field0 count))
(field2
(fxarithmetic-shift-right
field0 (fx- width count)))
(field (fxior field1 field2)))
(fxcopy-bit-field n start end field))
n))
[procedure] (fxreverse-bit-field fx1 fx2 fx3)
fx2 と fx3 は非負で (fixnum-width) より小さくなければならない。さらに、 fx2 は fx3 以下でなければならない。 fxrevese-bit-field 手続きは fx1 の fx2 から(これを含む) fx3 まで(これを含まない)までの位置のビットを逆向きにして得られる fixnum を返す。
(fxreverse-bit-field #b1010010 1 4)
⇒ 88 ; #b1011000