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
在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 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等。
在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 |
字符串的语法与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 |
(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