SBCL:将(unsigned-byte 32)转换为单精度浮点数

7

我有一个包含大量数据的 (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个回答

4

你可以这样写(declare (optimize (safety 0)) (type (signed-byte 32) x)))。这似乎会生成更短的汇编(它甚至优化了未使用的if分支),并且产生相同的结果。我建议仔细审核汇编代码,并通过彻底的回归测试确保代码安全。


的确,这产生了正确的汇编代码。当然,在这种情况下整个“if”语句是不必要的。但是话说回来,这是一个有点hackish的解决方案,虽然它与当前版本一起工作,但我认为通常不安全假设它在未来也能这样运行。总体而言暂时足够好 - 谢谢! - jlahd

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接