Mar*_*ark 3 lisp for-loop bit-manipulation sbcl common-lisp
假设我有一个整数,如二进制的109,1101101.如何迭代这个数字的位,例如:[64,32,8,4,1]?在lisp中这样做的好方法是什么?我应该通过添加一个案例来修改for宏,还是应该将整数转换为位向量或列表?
如果你只想处理"1",那么如果那些很少,那么遍历所有位是没有效率的.这是我在这种情况下要做的
(defmacro do-bits ((var x) &rest body)
"Evaluates [body] forms after binding [var] to each set bit in [x]"
(let ((k (gensym)))
`(do ((,k ,x (logand ,k (1- ,k))))
((= ,k 0))
(let ((,var (logand ,k (- ,k))))
,@body))))
Run Code Online (Sandbox Code Playgroud)
它使用了很好的2补码事实,即bit-anding一个数字,而它的相反返回最低有效设置位,而bit-anding数字和一个小于数字的数字将这个最低有效设置位归零.
请注意,此处理从最低有效位设置到最高有效位(在您的示例中使用了相反的顺序)
查看logbitp,它允许您访问整数的各个位.例如,
(loop for i below (integer-length 109)
collect (if (logbitp i 109) 1 0))
=> (1 0 1 1 0 1 1)
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
547 次 |
最近记录: |