lisp - 如何将给定八位位组(字节)的最后 n 位设置为零?

标签 lisp common-lisp bit-manipulation

我有一个八位字节(字节)和一些相关位,我想保留该给定字节的前 n 个(相关位)并将其余位设置为零。

例如

前 4 位相关的数字 217 将转换为 208

0                    0
0 1 2 3 4 5 6 7      0 1 2 3 4 5 6 7
+-+-+-+-+-+-+-+  ==> +-+-+-+-+-+-+-+
1 1 0 1 1 0 0 1      1 1 0 1 0 0 0 0

前 8 位(或更多位)相关的数字 255 根本不会改变

0                    0
0 1 2 3 4 5 6 7      0 1 2 3 4 5 6 7
+-+-+-+-+-+-+-+  ==> +-+-+-+-+-+-+-+
1 1 1 1 1 1 1 1      1 1 1 1 1 1 1 1

我写了这个函数来解决问题

(defun list-of-bits (integer)
  (let ((bits '()))
    (dotimes (position (integer-length integer) bits)
      (push (ldb (byte 1 position) integer) bits))))

(defun calculate-octet (byte rel-bits)
  (if (< rel-bits 8)
      (parse-integer 
       (FORMAT nil "~{~a~}"
           (replace (list-of-bits byte)
            '(0 0 0 0 0 0 0 0) 
            :start1 rel-bits
            :end1 8
            :start2 0
            :end2 rel-bits))
       :radix 2)
      byte))

但由于两个原因,这个解决方案似乎很糟糕

  1. 它在处理之前将整数拆分为一个列表

  2. 它将列表打印成一个字符串,然后再次解析

我知道 common-lisp 提供了直接访问位和字节的函数(ldb、logbitp),但我想不出一种方法来使用它们来解决我的问题。

有没有办法更有效(或至少更优雅)地解决问题?

最佳答案

CL-USER 6 > (mask-field (byte 4 4) 217)
208

另请注意,它不会屏蔽原始数字的字段,而是返回一个屏蔽了位字段的新数字。

关于lisp - 如何将给定八位位组(字节)的最后 n 位设置为零?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26068869/

相关文章:

按部分搜索单词

lisp - 如何让sbcl自动加载核心?

lisp - Quicklisp QUICKLOAD 应该放在我的源代码中的什么位置?无处?

lisp - 为什么有些人使用 #'(lambda 而不是 (Common Lisp 中的 lambda?

javascript - 对于 JavaScript 字符串等场景,base128 编码的可行性如何?

c - a >> ((sizeof a) * CHAR_BIT) 是定义的,UB 还是 IDB?

lambda - 如何生成和运行随机 lambda 表达式?

windows - Windows 中普通 lisp emacs + slime + sbcl 的自动缩进

list - 通过与 Common Lisp 中的 alist 进行比较来删除列表中的子列表

java - 带符号字节的按位与运算