個人用のSchemeの数に関するまとめ.
機械的な表現ではなく, 数学的な型で取り扱うことができる.
number?
- 数complex?
- 複素数real?
- 実数rational?
- 有理数integer?
- 整数
number?
は数以外の型判定の述語全てと直交するが,
上記の数値の型同士は直交した型ではなく,
上位の型は常に下位の型を拡張したものとなる.
型の判定は内部表現に依存せず,
常に数学的にどう言えるかで判定する.
例えば 3
3.0
3+0i
は全て整数であり,
有理数であり, 実数であり, 複素数である.
数値の型は, 処理系の内部表現と一対一対応しないため,
同じ整数 3
でもメモリ上の表現はいくつかの種類があることになる.
数学関数や四則演算/大小比較は,
異なる数値の型/内部表現の値でもジェネリックに利用できる.
fixnum
flonum
といったコンピュータ表現は型ではなく最適化ヒントに抑えるほうが好み
- 手続き
numerator
とdenominator
は分子と分母を返す - 分母は必ず正である
- おそらく有理数でない数からは計算できない
数値の型と直交して, 正確か非正確かという分類をする.
(非正確な数は誤差を持つということ)
正確な数を正確な演算する限り, 数は正確さを保つことができる.
非正確な数や非正確な演算が行われると, その結果を非正確な数になり,
(exact z)
で最も近い正確な数に戻すまで, 非正確なまま扱われる.
R5RSでは exact->inexact
と inexact->exact
だったが,
R6RSからは inexact
exact
になっている.
正確と非正確を行き来する際,
Scheme処理系は正確/非正確で同値(=)な数でなければエラーにできる.
- 正確と非正確の区別は, 浮動小数演算による誤差の伝播がわかるので好み
- 欲を言えば, 非正確な数に対する誤差を計測する手段が欲しい
- 整数は
3
10
など. - 小数は
3.14
などと書く. - 分数を扱うことができ
1/3
で有理数のリテラルとできる. - 指数表記
1e+3
なども可 - 複素数は
2+3i
と書くことができる - 複素数の極座標表記は
2@1.50
のように絶対値+偏角で表現できる- 偏角はラジアン角になるので, リテラルでの表記は手間
#b
#o
#d
#x
の接頭語で2,8,10,16進数表記ができる#i
#e
の接頭語で正確/非正確を明示的に表現できる
- 円周率やネイピア数などの数学定数が欲しい
infinite?
や nan?
で無限大や非数を判定することができる.
リテラルで書くと +inf.0
-inf.0
+nan.0
など.
- 複素数の構築は
make-rectangular
make-polar
で行う - 実部と虚部は
real-part
imag-part
で参照できる magunitude
とangle
で極座標成分を取得
複素数のリテラル表現や標準手続きの拡張で四元数をサポートする試み.
- ライブラリとして四元数を取り扱える言語はたくさんあるが, もし処理系が組み込みでサポートするものがあれば珍しいのではないか
+
*
-
/
で行う- 前置記法なのでできる面白いパターンがある
(+)
は0
(加法の単位元)(*)
は1
(乗法の単位元)(- x)
はx
の反数(/ x)
はx
の逆数
- 正の平方根は
sqrt
で求める - xのy乗は
expt
である. 他言語でよくあるpow
やpower
ではないので注意 - 自然指数関数は
exp
log
は1引数だとeを底として計算し, 2引数だと第二引数を底とする
- RnRSやSRFIの範囲では見受けられない
- 何かしらのライブラリを利用することが一般的と思われる
- RnRSやSRFIの範囲では見受けられない
- 何かしらのライブラリを利用することが一般的だろうか