我想用普通的 lisp 写一个位板,所以我需要一个 64 位整数。如何在普通的 lisp 中获得 64 位整数?此外,是否有任何图书馆可以帮助我完成这项工作而无需从头开始编写所有内容?
最佳答案
您可以将变量声明为 (signed-byte 64)
或 (unsigned-byte 64)
类型:
CL-USER> (typexpand '(unsigned-byte 64))
(INTEGER 0 18446744073709551615)
T
CL-USER> (typexpand '(signed-byte 64))
(INTEGER -9223372036854775808 9223372036854775807)
T
这取决于您的实现,它是否真的足够聪明,可以真正将其填充到 8 个连续字节中,或者它是否会为此使用 bignum。适当的优化
声明可能会有所帮助。
这是此类类型声明的一个(非常简单的)示例,并以二进制形式处理整数:
(let* ((x #b01)
(y #b10)
(z (logior x y)))
(declare ((signed-byte 64) x y z))
(format t "~a~%" (logbitp 1 x))
(format t "~a~%" (logbitp 1 (logior x (ash 1 1))))
(format t "~b~%" z))
Output:
NIL
T
11
这是一个 setf-expander 定义,用于为整数中的位获取一个简单的 setter,以及一个相应的 getter:
(define-setf-expander logbit (index place &environment env)
(multiple-value-bind (temps vals stores store-form access-form)
(get-setf-expansion place env)
(let ((i (gensym))
(store (gensym))
(stemp (first stores)))
(values `(,i ,@temps)
`(,index ,@vals)
`(,store)
`(let ((,stemp (dpb ,store (byte 1 ,i) ,access-form))
,@(cdr stores))
,store-form
,store)
`(logbit ,i ,access-form)))))
(defun logbit (index integer)
(ldb (byte 1 index) integer))
这些可以像这样使用:
(let ((x 1))
(setf (logbit 3 x) 1)
x)
==> 9
(let ((x 9))
(setf (logbit 3 x) 0)
x)
==> 1
(logbit 3 1)
==> 0
(logbit 3 9)
==> 1
关于lisp - 如何在普通的 lisp 中获取 64 位整数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8674982/