lisp - 如何在普通的 lisp 中获取 64 位整数?

标签 lisp common-lisp bit clisp

我想用普通的 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/

相关文章:

c - 有没有办法操纵我在 C 中移动的位

c++ - 使用 ofstream 将 4 位写入二进制文件

lisp - 使用带有 Common Lisp 的排序的意外列表重复

lisp - 如何在 lisp 中解决赋值问题

emacs - 如何在 Common Lisp 中隐藏(读取)输出

linux - 我如何使用(需要:PACKAGE) in clisp under Ubuntu Hardy?

lisp - 如何从 REPL 获得离线 CLHS?

c# - 如何在 C# 中将按位非运算符与移位运算符一起使用?

lisp - 如何使用重命名文件在 Lisp 中移动文件

lisp - clip正数创始人