如何在常见的lisp中将双浮点数转换为字节数组,反之亦然?

时间:2015-09-17 04:07:42

标签: lisp common-lisp

对于整数(32位或4字节),我可以这样做;

(defun get-u4 (arr pos)
  (let ((u4 0))
    (setf (ldb (byte 8 0) u4) (aref arr pos))
    (setf (ldb (byte 8 8) u4) (aref arr (+ pos 1)))
    (setf (ldb (byte 8 16) u4) (aref arr (+ pos 2)))
    (setf (ldb (byte 8 24) u4) (aref arr (+ pos 3)))
  u4))

(defun put-u4 (arr pos int)
  (setf (aref arr pos) (ldb (byte 8 0) int))
  (setf (aref arr (+ pos 1)) (ldb (byte 8 8) int))
  (setf (aref arr (+ pos 2)) (ldb (byte 8 16) int))
  (setf (aref arr (+ pos 3)) (ldb (byte 8 24) int)))

但是,我无法弄清楚如何为64位或8位执行此操作 双浮子?假设Little-Endianess。

=============

我找到了一个解决方案(使用外部库); https://www.quicklisp.org/beta/UNOFFICIAL/docs/ieee-floats/doc/index.html 使用这个,我可以使用适当的编码/解码双浮点到/从整数 大小

1 个答案:

答案 0 :(得分:1)

从维基百科我们得到this

enter image description here

enter image description here

您可以使用quicklisp获取评论中提到的库:

CL-USER> (ql:quickload 'ieee-floats)
To load "ieee-floats":
  Install 1 Quicklisp release:
    ieee-floats
; Fetching #<URL "http://beta.quicklisp.org/archive/ieee-floats/2015-06-08/ieee-floats-20150608-git.tgz">
; 4.92KB
==================================================
5,041 bytes in 0.01 seconds (378.68KB/sec)
; Loading "ieee-floats"
[package ieee-floats]
(IEEE-FLOATS)
CL-USER> (ieee-floats:encode-float32 23d2)
1158660096
CL-USER> (ieee-floats:decode-float32 #b010101)
2.9427268e-44
CL-USER> (ieee-floats:encode-float32 0)
; Evaluation aborted on #<TYPE-ERROR expected-type: FLOAT datum: 0>.
CL-USER> (ieee-floats:encode-float32 0.0)
0
CL-USER> (ieee-floats:encode-float32 0.1)
1036831949

你当然可以使用iee-floats:encode / decode-float64当然,

您还需要知道#b010101是一个宏,它表示您可以在普通数学中使用的二进制数字与常见的lisp:

CL-USER> (+ 2 #b10)
4

所以它将你的二进制文件转换为整数,然后你也可以使用格式为

的实用程序
(format nil "~B" 2)
"10"

你可以用来将整数转换为二进制字符串,最后你唯一可以注意的是在二进制数字之前的0自动完成,ieee库为表示删除它们

CL-USER> (ieee-floats:encode-float64 1.0d0)
4607182418800017408
CL-USER> (format nil "~B" *)
"11111111110000000000000000000000000000000000000000000000000000"
CL-USER> (length *)
62
CL-USER> (ieee-floats:encode-float64 -1.0d0)
13830554455654793216
CL-USER> (format nil "~B" *)
"1011111111110000000000000000000000000000000000000000000000000000"
CL-USER> (length *)
64

CL-USER> (ieee-floats:decode-float64 #b11111111110000000000000000000000000000000000000000000000000000 )
1.0d0
CL-USER> (ieee-floats:decode-float64 #b1011111111110000000000000000000000000000000000000000000000000000 )
-1.0d0
CL-USER> (ieee-floats:decode-float64 #b0011111111110000000000000000000000000000000000000000000000000000 )
1.0d0

有了这个,你可以做出所有你需要的转变,祝你好运