Common Lisp语法——数字,字符与字符串

数字(Numberic)

Common Lisp支持的数字类型有:整数、浮点数和复数。Common Lisp会把输入的数字表示形式化成其最简的表示形式。比如:

123          -> 123
+123         -> 123
-123         -> -123
123.         -> 123
2/3          -> 2/3    分数形式
-2/3         -> -2/3
4/6          -> 2/3
6/3          -> 2
#b10101      -> 21
#xa          -> 10
#o10         -> 8
#5r23        -> 13

前缀#X或#x代表16进制数,#O或#o代表8进制数,#B或#b代表二进制数。同时还可以按自定义进制来书写数字,方式为#nR最为前缀,n的取值范围是[2,36],当大于9的数,则用A-Z或a-z来表示。

在Common Lisp中将浮点数细分为了四种子类型:short, single, double和long。不同的子类型使用不同的bit位数来存储浮点数。可以通过s,f,d,l四个指数表示符来指定浮点数的具体类型,它们分别表示short,single,double和long floats。同时它们又是指数幂的分隔符。字母e则是用默认的浮点数类型(single-float)来表示浮点数。如下:

1.0        -> 1.0
1e0        -> 1.0    signle类型
1d0        -> 1.0d0  double类型
1s0        -> 1.0s0  short类型
1L0        -> 1.0L0  long 类型
123.0      -> 123.0
123e0      -> 123.0
0.123      -> 0.123
.123       -> 0.123
123e-3     -> 0.123
0.123e20   -> 1.23e+19
123d23     -> 1.23d+25
最后,前缀为#C或#c后跟一个含有两个实数的list则表示一个复数。实际上,共有5种类型的复数,因为实部和虚部必须都为有理数或则都为浮点数。但是可以用任何数字表达形式来书写复数的实部和虚部。如果实部和虚部的数字类型不同,Lisp则会对这两部分的数据类型做类型提升。

#c(2 1)        -> #c(2 1)
#c(2/3 3/4)    -> #c(2/3 3/4)
#c(2 1.0)      -> #c(2.0 1.0)
#c(2.0 1.0d0)  -> #c(2.0d0 1.0d0)
#c(1/2 1.0)    -> #c(0.5 1.0)
#c(3 0)        -> 3
#c(3.0 0.0)    -> #c(3.0 0.0)
#c(1/2 0)      -> 1/2
#c(-6/3 0)     -> -2

基础运算

四个函数+, - , * 和/分别提供了加、减、乘和除四种基础运算。+和*可以有任意个数的参数,-和/可以有不少于1个参数的任意个数参数。当+无参数时返回0,*无参数时返回1.

(+ 1 2)              -> 3
(+ 1 2 3)            -> 6
(+ 12.0 2.4)         -> 14.4
(+ #c(1 2) #c(3 4))  -> #c(4 6)
(/ 2 3.0)            -> 0.6666667
可通过FLOOR(向下截断)和CEILING(向上截断)操作符将实数转换为整数。

而TRUNCATE则是向0截断,当对整数而言其等同于FLOOR,对负数而言则等同于CEILING。

ROUND则是向距离最近的一个整数截断(四舍五入)。

MOD用于取模,而REM则用于求余。(注意理解取模与求余的区别)

(+ (* (floor (/ x y) ) y) (mod x y))     等价于 x
(+ (* (truncate (/ x y)) y (rem x y)) 等价于 x

宏INCF,DECF, 1+和1-:

(incf x)      等价于  (setf x (1+ x)) 等价于 (setf x (+ x 1))
(decf x)      等价于  (setf x (1- x)) 等价于 (setf x (- x 1))
(incf x 10)   等价于  (setf x (+ x 10))
(decf x 10)   等价于  (setf x (- x 10))

数字的比较

函数=用于判断数字是否相等,它在比较数字时不会区分数字的具体类型。而不同的EQL将会关注数字的类型。当=函数的参数多余两个时,只有当它们都相等时才返回true。

(= 1 1)                        -> T
(= 10 20/2)                    -> T
(= 1 1.0 #c(1.0 0.0) #c(1 0))  -> T
函数/=在其所有参数均不等的时候返回true:

(/= 1 1)       -> NIL
(/= 1 2)       -> T
(/= 1 2 3)     -> T
(/= 1 2 3 1.0) -> NIL

函数<, >, <= 和>=用于比较实数的大小。与=和/=函数相识,它们都可以接收多个参数:


(< 2 3)       -> T
(> 2 3)       -> NIL
(<= 2 3 3 4)  -> T
(<= 2 3 4 3)  -> NIL
函数MAX和MIN分别用于获取任意个数的实数中的最大和最小值。
(max 2 4 3 1) -> 4
(min 2 4 3 1) -> 1

函数ZEROP,MINUSP和PLUSP分别用于判断一个实数是否为0,小于0和大于0。

EVENP和ODDP用于判断一个整数为偶数和奇数。

同样Lisp也提供了一些高级数学工具:LOG(对数),EXP(幂数),SIN,COS,TAN,ASIN,ACOS,ATAN等。

字符(Characters)

在Lisp中表示字符的方法为:前缀#\和跟字符,#\后几乎可以跟任何字符(除双引号,空格等)。可以用#\space表示空格字符,其他的有:newline tab page rubout linefeed return和Backspace等。

字符的比较如下表:

Number Analog
Case-Sensitive
Case-Insensitive
= CHAR= CHAR-EQUAL
/= CHAR/= CHAR-NOT-EQUAL
< CHAR< CHAR-LESSP
> CHAR> CHAR-GREATERP
<= CHAR<= CHAR-NOT-GREATERP
>= CHAR>= CHAR-NOT-LESSP

字符串(Strings)

字符串的语法与C语言的类似。由双引号(" ")所限定的一系列字符,当需要包含一些特殊的字符时,可以使用反斜杠(\)作为转意符来表现特殊的字符。

 "foobar"  ; 简单字符串,foobar
"foo\"bar" ; 反斜杠转义双引号,foo"bar
"foo\bar"  ; 反斜杠转义b, foobar
字符串比较:

Numeric Analog Case-Senstive Case-Insensitive
= STRING= STRING-EQUAL
/= STRING/= STRING-NOT-EQUAL
< STRING< STRING-LESSP
> STRING> STRING-GREATERP
<= STRING<= STRING-NOT-GREATERP
>= STRING>= STRING-NOT-LESSP
与字符比较不同的是,字符串比较只能比较两个字符串。在比较时可以通过:start1,:end1,:start2,:end2来指定子字符串的比较(:end1和:end2可以为NIL):

(string= "foobarbaz" "quuxbarfoo" :start1 3 :end1 7 :start2 4 :end2 7)
所有的字符串比较(除STRING=和STRING-EQUAL)都会返回字符串中第一个不相等的字符的索引:

(string/= "lisp" "lissome")                   -> 3
(string< "lisp" "lisper")                     -> 4
(string< "foobar" "abaz" :start1 3 :start2 1) -> 5 注意不是2

你可能感兴趣的:(Common,Lisp)