在大多数机器上,表示的范围是 -134217728 到 134217727 之间的数,也就是 28 比特。也有的机器上可能表示更大的范围。值得注意的是, Emacs Lisp 不检查溢出。也就是说,有可能 (1+ 134217727) 的结果就 是 -134217728 。
integer 的 read syntax 和我们平时使用整数的习惯很类似,用 十进制表示。
-1 ; The integer -1.
1 ; The integer 1.
1. ; Also the integer 1.
+1 ; Also the integer 1.
268435457 ; Also the integer 1 on a 28-bit implementation.
0 ; The integer 0.
-0 ; The integer 0.
也可以用其他进制表示一个整数
#b1000 ; 二进制,表示 8 ,
#o10 ; 八进制,也是 8 , 注意是字母 o ,不是数字 0 。
#x10 ; 十六进制,表示 16,
Emacs Lisp 采用补码表示一个数。如果是 28 比特的话,那么 5 的二进制表示是
0000 0000 0000 0000 0000 0000 0101
1111 1111 1111 1111 1111 1111 1011
浮点数表示小数。精度和范围和实现的计算机相关。
浮点数的 read syntax 也和我们平时的使用习惯一致,例如 `1500.0', `15e2', `15.0e2', `1.5e3', 和 `.15e4' 都表示1500.0 这样一个浮点数。
floatp 用于判断一个 object 是否是一个浮点数。
(floatp 1) ; => nil (floatp 0.0) ; => t (floatp 0) ; => nil (floatp 1.0) ; => t
integerp 用于判断一个 object 是否是一个 integer 。
(integerp 1) ; => t (integerp 0.0) ; => nil (integerp 0) ; => t (integerp 1.0) ; => nil
注意到一个很重要的区别, 1 是一个 integer , 1.0 是一个float ,他们拥有不一样的 type 。是两个不同的 object 。可以从 read syntax 中很容易区分出来两种不同的 number 。
numberp 用于判断一个 object 是否是一个 number 。 number 类型是 integer 和 float 的并集。
(numberp 1) ; => t (numberp 1.0) ; => twholenump 用于判断一个 object 是否是一个非负整数。
(wholenump 1.0) ; => nil (wholenump -1 ) ; => nil (wholenump 1) ; => t (wholenump 0) ; => tzerop 用于判断一个 object 是否是零 。
(zerop 0.0) ; t (zerop 0) ; t
加减法的函数可以接受任何 number 的类型的object 最为参数。
(+ 1 1) ; => 2 (+ 1 1 1.0 3.0) ; => 6.0 (- 1 2 3) ; => -4 , 也就是 1 - 2 -3 (integerp (+ 1. 1)) ; =>t (integerp (+ 1.0 1)) ; =>nil (floatp (+ 1.0 1)) ; =>t
如果所有参数都是 integer 的 object ,那么函数返回一个 integer 。 如果参数中有一个的 float 的 object ,那么返回一 个 float object 。
加减法还可以接受一个参数,或者没有参数也可以。
(+ 100) ; => 100 (- 100) ; => 100 (+ ) ; => 0 (- ) ; => 0
这个特点在是很用的。例如,我们有一个 list ,其中的元素都是 number 。那么我们很容易对其求和。
(setq a-number-list '( 1 2 3 4 5 6 7 8 9 10)) (apply '+ a-number-list) ; => 55
如果 a-number-list 中只有一个元素或者没有任何元素,我们
一样可以得到一个合理的结果。
如果乘除法中存在一个 float 的参数,那么就执行 float 的 乘除 法。
float 的除法和 integer 的除法是有区别的。 float 的除法和我 们平常使用的算术很类似。 但是 integer 的除法只返回商,而不 管余数。 如果想得到余数必须使用取模的函数。
和加减法类似,一样可以做连乘或者连除。取模的函数是只能接受 两个参数。
(* 2.0 4 ) ; => 8.0 , 一个 float (* 2 4) ; => 8 , 一个 integer (* 2.0 4.0 5) ; => 40.0 ,一个 float (/ 10.0 4) ; => 2.5 , 一个 float (/ 12.0 4) ; => 3.0 , 一个 float (/ 24 4 3) ; => 2 , 一个 integer (/ 13 4) ; => 3 , 商是 3 , 一个 integer (% 13 4) ; => 1 , 余数是 1 .
乘法可以接受一个参数,或者一个参数都没有也行。除法必须要有 两个或者两个以上的参数。
(* ) ; 返回 1 (* 100) ; 返回 100
和其他语言不同对于一些,Emacs Lisp 中的加减乘除也是一个函 数,而不是一个操作符。这样就不存在操作符优先级的问题。
通常我们使用 `' 函数来判断两个 number 是否相等。也可以用
>, <= , > , < , 来判断两个 number 的大小关系。
可以用 max 和 min 函数得到最大值或者最小值。
( > 100 200) ; => nil ( < 100 200) ; => t (max 100) ; => 100 (min 100) ; => 100 (max 1 2 3 4) ; => 4 (min 1 2 3 4) ; => 1
float 函数把一个 number 转换成为一个 number , truncate 把 一个 number 转换成为一个 integer 。
(float 1) ; => 1.0 (float 1.0) ; => 1.0 (truncate 1.2) ; => 1 (truncate 1.7) ; => 1 (truncate -1.2); => -1 (truncate -1.7); => -1
floor 函数和 ceiling 函数对应数学中的上取整函数和下取整函 数。round 函数表示四舍五入。
(floor 1.2)
=> 1
(floor 1.7)
=> 1
(floor -1.2)
=> -2
(floor -1.7)
=> -2
(ceiling 1.2)
=> 2
(ceiling 1.7)
=> 2
(ceiling -1.2)
=> -1
(ceiling -1.7)
=> -1
(round 1.2)
=> 1
(round 1.7)
=> 2
(round -1.2)
=> -1
(round -1.7)
=> -2
与他们对应的函数还有 ffloor , fceiling , ftruncate,
fround ,区别是他们返回的是一个 float ,而不是一个
integer 。
lsh, ash 函数用来完成位移动。 例如
(lsh 4 3) ; => 32
表示把 4 左移 3 位, 如果第二个参数是负数表示右移。
lsh 和 ash 基本上功能一样,但是如果右移一个负数的时候,两 个就有区别了, lsh 是在高位补零, ash 在高位补一,用 ash 右移一个负数,结果一定是负数,而 lsh 就一定得到一个正书。
logand , logior , logxor 分别是逻辑与函数,逻辑或函数和逻 辑异或函数。lognot 逻辑取反函数。
random 函数可以返回一个伪随机数,一个 integer 。
abs , sin, cos, tan, asin, acos, exp, log, log10, expt, sqrt 。
(eq (* (/ 1 3.0) 3) 1.0) ;;返回 nil (equal 1.0 1) ;; 返回 nil (= 1.0 1) ;;返回 t
看起来很复杂,其实使用起来很容易, 如果比较数字的时候,就用 = , 如果比较两个对象是 否是同一个时用 eq , 其他时候用 equal .
(setq a
(mapcar (lambda (x)
(random))
(make-list 10 0)))
(defun get-greater-less-list (x a-list)
(if (not a-list)
(cons nil nil)
(let* ((a-tail (cdr a-list))
(a-head (car a-list))
(a-b (get-greater-less-list x a-tail))
(greater-list (car a-b))
(less-list (cdr a-b)))
(if (< x a-head)
(cons
(cons a-head greater-list)
less-list)
(cons
greater-list
(cons a-head less-list))))))
(get-greater-less-list 0 a)
(quick-sort a)
(defun quick-sort ( a-list)
(if (not a-list)
nil
(let* ((a-head (car a-list))
(a-tail (cdr a-list))
(a-b (get-greater-less-list a-head a-tail)))
(append
(quick-sort (car a-b))
(cons
a-head
(quick-sort (cdr a-b)))))))