3. その結果を表示する
3.6 さまざまなデータ型 ( その 1)
3.6.1 ブール型
ブール型
(boolean)
は真偽を表すデータ型です。真を表すデータは #tで、 偽を表すデータは #fです。 ブール型のデータは後で説明する条件式if やcondの条件判定部などで、
ある条件が成立するかを調べるのに使われます11。
ブ ール型のデータは評価されてもそれ自身を値として持ちます。そのためプログラム に中に書くときは、引用符をつけないてすみます。このようなデータは 自己評価的
(self-evaluating)
である、と呼ばれています。> #t
#t
10この他にも、文字型、ベクトル、手続き、継続などがあります。
11厳密なことをいえば 、
Scheme
の条件式では #fのみが条件の偽として取り扱われ 、 それ以外の場合は 真とみなされます。> #f
#f
> '#t
#t
与えられたデータがブール型のデータかど うかを判定するには、手続きboolean? を使 います。
} (boolean? hデータi)
|
hデータiがブール型のデータなら真 #tを、そうでなければ偽 #f を返します。> (boolean? #t)
#t
> (boolean? #f)
#t
> (boolean? 10)
#f
> (boolean? '(1 2 3))
#f
> (boolean? '())
#f
ブール値の真と偽を反転させるには、手続き notを使います。
} (not hデータi)
|
hデータiが #f なら #t を、そうでなければ #fを返します。(
hデータiは必ずしもブール型のデータでなくてもかまいません。
)
> (not #t)
#f
> (not #f)
#t
> (not 10)
#f
> (not (cons 1 2))
#f
> (not '())
#f
3.6.2 数
Scheme
では数(numbers)
を取り扱うことができます。これまでの例では整数しか使いませんでしたが、
Scheme
では整数(integer)
、有理数(rational)
、実数(real)
、複素数(complex)
の
4
つの部分型が用意されています。(Scheme
処理系によっては用意されていない型があ るかもしれません。)
ここでは整数と実数について説明します。なお数のデータ型は演算 結果に応じて変化します。例えば4
は整数型ですが 、これに1 : 5
をかければその結果は実 数型の6 : 0
になります。数に対する演算には、次のものが用意されています。
} (+
x
1x
2 )| x
1+ x
2+
} (-
x
)|
,x
} (-
x
1x
2)| x
1 ,x
24 (-
x
1x
2x
3 )| x
1,x
2,x
3,(
処理系によってはこの形式での使い方ができないことがある ので注意して下さい。)
} (*
x
1x
2 )| x
1x
2} (/
x
)| 1 =x
} (/
x
1x
2)| x
1=x
24 (/
x
1x
2x
3 )| x
1= ( x
2x
3) (
処理系によってはこの形式での使い方ができないことがあるので 注意して下さい。)
} (min
x
1x
2 )| x
1;x
2;
の中の最小値} (max
x
1x
2 )| x
1;x
2の中の最大値} (abs
x
)| x
の絶対値} (floor
x
)| x
よりも大きくない最大の整数} (ceiling
x
)| x
よりも小さくない最小の整数} (truncate
x
)|
小数点以下を切捨てる} (round
x
)|
小数点以下を四捨五入する 例を見てみましょう。> (+ 2 4)
6
|
演算結果は整数6
> (+ 2 4.0)
+6.0
|
演算結果は実数6.0
> (- 2 3) -1
> (- 3) -3
> (* 3.0 4.5) +13.5
> (/ 10 5) 2
> (/ 10 5.0) +2.0
> (max 1 3 4 5 10 23) 23
> (min 4 2 8 10) 2
> (abs -8) 8
> (floor 10.3) 10
> (floor -10.3)
-11
> (ceiling 10.3) 11
> (ceiling -10.3) -10
> (round -10.3) -10
整数に関する演算手続きとして、次のものがあります。
} (gcd
n
1n
2)|
最大公約数} (lcm
n
1n
2)|
最小公倍数} (quotient
n
1n
2)|
商} (remainder
n
1n
2)|
剰余} (modulo
n
1n
2)|
剰余gcd と lcm は 、それぞ れ 最大公約数と 最小公倍数を 求め る手続きで す。quotient
,
remainder
,
modulo は、それぞれ次の値を返します。(quotient
n
1n
2) )n
3(remainder
n
1n
2) )n
4(modulo
n
1n
2) )n
4ただし 、
n
1= n
2n
3+ n
4 で、しかも0
n
4< n
2 です。( n
3 は商を、n
4は剰余を表しています。
)
引数が負のときは、remainder と modulo は違う値を返します。> (remainder 17 3) 2
> (modulo 17 3) 2
> (remainder -17 3) -2
> (modulo -17 3) 1
数に関する述語12として、次の手続きが用意されています。
} (=
x
1x
2 )| x
1= x
2=
か?
} (<
x
1x
2 )| x
1< x
2<
か?
} (>
x
1x
2 )| x
1> x
2>
か?
} (<=
x
1x
2 )| x
1x
2 か?
} (>=
x
1x
2)| x
1x
2 か?
} (zero?
x
)| x
は零か?
} (positive?
x
)| x
は正か?
} (negative?
x
)| x
は負か?
} (odd?
n
)| n
は奇数か?
} (even?
n
)| n
は偶数か?
これらの実行例を見てみましょう。
> (= 3 3 3)
#t
> (= 1 3 3)
#f
12
じゅつご
述 語とは、ある性質が成り立つかど うかを調べるものをいいます。
> (< 3 4 5)
#t
> (<= 3 3 4 4 6)
#t
> (zero? 2)
#f
> (zero? 0)
#t
> (positive? 2)
#t
> (negative? -2)
#t
> (odd? 3)
#t
> (odd? 2)
#f
> (even? 2)
#t
データ型を調べるための手続きも用意されています。
} (number?
x
)| x
が数(
整数/
有理数/
実数/
複素数のいずれか)
なら #tが返され 、そうでなけれ ば #fが返されます。} (integer?
x
)| x
が整数なら #tが返され、そうでなければ #fが返されます。例外として、x
が実数でも、 小数部分が
0
のときは #tが返されます。} (real?
x
)| x
が実数なら #tが返され 、そうでなければ #fが返されます。(
整数は実数の特別な場合みなせますので、
x
が整数のときも #tが返されます。)
これらを試してみましょう。
> (number? 'foobar)
#f
> (number? 8.2)
#t
> (number? 2)
#t
> (integer? 8.2)
#f
> (real? 8.2)
#t
> (integer? 2)
#t
> (integer? 2.0)
#t
> (real? 100)
#t
計算機の内部では、実数と整数とでは表現形式がまったく違います。取り扱える範囲を 越えない限り、整数の演算は誤差なくできます。ですが 、実数はコンピューター内部では 近似値で保持されるので 、ど うしても誤差が生じてし まいます。
(
ほとんど の計算機は 、ふど うしょうすうてん
浮動小数点と呼ばれる形式で実数を計算機内部に保持しています。
)
たとえば10
割る3
を計算し 、コンピューター内部に保持することを考えてみましょう。計算結果は
3 : 3333
と、無限に
3
が続きます。そのために、この結果を保持するには無限に多くの記憶領域が 必要になります。ですがそれは不可能なので、あるところで切って値を保持せざ るを得ません。
3 : 33333
として保持したとすれば 、本当の値とは少し違っていることが分かると思います。保持する桁数を多くすれば本当の値に近くなりますが 、それでも本当の値とはわ ずかに違っています。
手続き real? は整数 1 に対して #t を返しますし 、手続き integer? は実数 1.00 に 対しても #t を返します。ですがさきほど 説明した誤差の理由で、整数なのか実数なのか を厳密に調べたいことがあります。そのため手続き integer? と real? では 、数がコン ピューター内部で整数として保持されているのか、それとも実数として保持されているの かを知ることができません。
Scheme
ではこの概念を厳密性(exactness)
という言葉で表現しています。コンピューター内部で誤差が生じない形で保持されているものを厳密数
(exact number)
と呼び 、そうでないものを非厳密数
(inexact number)
と呼んでいます。数が厳密数か非厳密数かを調べるのには、次の手続きを使います。
} (exact?
x
)| x
の値が厳密数なら真#t を、そうでなければ偽 #f を返します。} (inexact?
x
)| x
の値が非厳密数なら真 #tを、そうでなければ偽 #f を返します。4 (inexact->exact
n
)|
非厳密数n
を厳密数に変換します。4 (exact->inexact
n
)|
厳密数n
を非厳密数に変換します。これらを試してみましょう。
> (exact? 1)
#t
> (integer? 1.0)
#t
> (exact? 1.0)
#f
> (real? 1)
#t
> (inexact? 1)
#f
> (inexact? 1.0)
#t
> (inexact->exact 4.4) 4
> (inexact->exact 4.5) 5
> (exact->inexact 4) 4.0
この他に、三角関数や指数関数なども用意されています13。
4 (exp
x
)|
指数関数e x ( e
は自然対数の底)
4 (log
x
)|
対数関数log e x
4 (sin
x
)|
正弦関数sin x
4 (cos
x
)|
余弦関数cos x
4 (tan
x
)|
正接関数tan x
13これらは
Scheme
に必須の手続きと定められていません。そのため、処理系によっては用意されていない場合があります。
4 (asin
x
)|
逆正弦関数sin
,1x
4 (acos
x
)|
逆余弦関数cos
,1x
4 (atan
x
)|
逆正接関数tan
,1x
4 (atan
y x
)|
逆正接関数tan
,1y=x
4 (sqrt
x
)|
平方根px
4 (expt