sbcl:将(unsigned-byte 32)转换为单浮点数

时间:2013-12-19 07:33:53

标签: common-lisp sbcl

我有一个(unsigned-byte 32)数组,其中包含大量数据,其中一些数据采用浮点格式。也就是说,一些字节被处理为包含位字段的整数,而其中一些字节作为32位浮点数。

我需要读取和写入数组中的数据。

不幸的是,函数sb-kernel:make-single-float接受了(signed-byte 32)的参数,sb-kernel:single-float-bits也返回了一个带符号的单词,因此它们与我的向量不直接兼容。另一方面,将向量转换为包含有符号字节将使位字段操作变得痛苦。

到目前为止,我已经写过了

(defun u32-to-sf (x)
  (declare (optimize (speed 3) (compilation-speed 0) (debug 0))
           (type (unsigned-byte 32) x))
  (if (>= x #x80000000)
      (sb-kernel:make-single-float (- x #x100000000))
      (sb-kernel:make-single-float x)))

它做了正确的事情,但生成的程序集看起来很难看它的条件跳转和不必要的比较和减法。

关于如何说服sbcl简单地接受unsigned-byte的按位内容作为浮动的按位内容的任何想法?

1 个答案:

答案 0 :(得分:3)

你可以(declare (optimize (safety 0)) (type (signed-byte 32) x)))。这似乎产生了更短的装配(它甚至优化了未使用的if分支)和相同的结果。我建议仔细检查装配,并通过彻底的回归测试确保装配。