明经CAD社区

 找回密码
 注册

QQ登录

只需一步,快速开始

搜索
查看: 544|回复: 2

浮点数与16进制字符串互转

[复制链接]
发表于 2024-7-5 14:10:10 | 显示全部楼层 |阅读模式

在部分二进制文件中,浮点数是需要转换换为16进制字符串来存储的。
由于在LISP中没有单精度浮点数和双精度浮点数转16进制字符串函数,前些天为此伤透脑筋,有偿悬赏也未有人帮忙解决。
在查阅算法以及论坛资料后,算是完美解决了这个难题。

其中引用了大神baitang36大神的的内部函数itoa,以及高飞鸟大神的激活内部函数的代码,在此拜谢!
程序源代码如下,由于不会使用上传代码工具,敬请谅解


;;=============================================================
;;; 程序加载后,就可以用tranf来激活一个系统隐藏的函数           
;;; 用法:(tranf "内部函数名")                                 
;;; 参数:函数名的字符串                                       
;;; 返回:T存在或者是可用的内部函数,nil不存在或则无效         
;;; 作者:highflybird                                          
;;; 例子:(tranf "get-logical-drives")                          
;;; 此程序得到网友baitang36和不死猫的大力帮助,特此致谢!      
;;; 另外借鉴了tryhi和其他网友的代码,在此一并感谢!            
;;;-------------------------------------------------------------
(defun HFB-LOAD-TRANF (/ f o l s b)
  (setq o (strcat (getenv "UserProfile") "\\Intern.fas"))
  (if (findfile o)
    (vl-file-delete o)
  )
  (setq        l '(70         65   83   52        45   70          73   76   69         13   49   13
            49         32   36   1        36   51          51   32   48         32   36   86
            58         76   80   80        0    105  110  116  101         114  110  0
            108         112  112  45        115  121  109  102  117         110  45   62
            97         108  0           0        57   3          0    22   36
           )
  )
  (setq b (vlax-make-safearray 17 (cons 0 (1- (length l)))))
  (vlax-safearray-fill b l)
  (setq s (vlax-create-object "ADODB.Stream"))
  (vlax-put s 'type 1)
  (vlax-invoke s 'open)
  (vlax-invoke-method s 'Write b)
  (vlax-invoke s 'saveToFile o 2)
  (vlax-invoke s 'close)
  (vlax-release-object s)
  (mapcar
    'set
    '(:lpp intern lpp-symfun->al)
    (mapcar 'eval (load o))
  )
  (vl-file-delete o)
  (defun tranf (s) (lpp-symfun->al (intern s :lpp)))
  (tranf 'al-add-subr-name)
  (mapcar
    'al-add-subr-name
    '(al-add-subr-name lpp-symfun->al intern tranf)
  )
  (if lpp-symfun->al
    (princ "\n已打开内部函数转普通函数大门.\n")
    (princ "\n激活内部函数转普通函数失败!\n")
  )
)
;激活保留函数功能的自定义函数
(or lpp-symfun->al (HFB-LOAD-TRANF))

;激活itoa进制转换函数(itoa [int] [进制 int])最多32进制
(tranf "itoa")

;字符串分段函数
;参数 str 类型sting
;参数 dimod 当dimod为int时,按int分割(string-Split "asfsgsb" 2)-> '( "as" "fs" gs" b")
;参数 dimod 当dimod为string时,按string 分割(string-Split "assfssgssb" "ss" )-> '( "a" "f" g" b")
(defun string-Split (str dimod / str dimod n nlst)
  (if (= (TYPE dimod) 'INT)
    (progn
      (setq n         1
            nlst nil
      )
      (while (<= n (strlen STR))
        (setq nlst (cons (substr str n dimod) nlst))
        (setq n (+ n dimod))
      )
      (reverse nlst)
    )
    (progn
      (while (setq n (vl-string-search dimod str))
        (setq nlst (cons (substr str 1 n) nlst)
              str  (substr str (+ 1 (strlen dimod) n))
        )
      )
      (reverse (cons str nlst))
    )
  )
)

;二进制字符串转整数
;(2str-to-int "1101")->13
(defun 2str-to-int(str / n int)
  (setq n (strlen str) int 0)
  (while (/= str "")
    (setq n (- n 1))
    (if (= "1" (substr str 1 1))
      (setq int (+ int (expt 2 n)))
      )
    (setq str (substr str 2))
    )
  int
  )
;32float2hex单精度浮点数转16进制字符串
;real 单精度浮点数(此处用小数表示)
;(32float2hex 117.1468)->"42EA4B29"
(defun 32float2hex (real / 16str 2str N laststr 2strlst 2strtointlst
                  16strlst)
  (if (equal real 0 0.00000000000001)
    (setq 16str "00000000")
    (progn
                                        ;判断符号位
      (if (> real 0)
        (setq 2str "0")
        (setq 2str "1")
      )
      (setq real (abs real))
      (SETQ N 127)
      (WHILE (< 2 REAL)
        (SETQ REAL (/ REAL 2.0))
        (SETQ N (1+ N))
      )
      (setq 2str (strcat 2str (itoa n 2))) ;增加阶码位
      (setq real (1- real))                ;取尾数部分
      (setq laststr "")                        ;尾数部分二进制初始值
      (repeat 23;尾数位数
        (setq real (* 2.0 real))
        (if (>= real 1)
          (progn (setq laststr (strcat laststr "1"))
                 (setq real (1- real))
          )
          (setq laststr (strcat laststr "0"))
        )
      )
      (setq 2str (strcat 2str laststr))        ;完整的32位二进制
      (setq 2strlst (string-Split 2str 4)) ;每四位分割成表
      (setq 2strtointlst (mapcar '2str-to-int 2strlst))
                                        ;每四位转换成十进制整数
      (setq 16strlst (mapcar '(lambda (X) (itoa x 16)) 2strtointlst))
                                        ;每个整数转换为16进制字符串
      (setq 16str (strcase(apply 'strcat 16strlst))) ;表中字符串按顺序合并
    )
  )
)
;64float2hex双精度浮点数转16进制字符串
;real 双精度浮点数(此处用小数表示)
;(64float2hex 117.1468)->"405D49652BD3C361"
(defun 64float2hex (real / 16str 2str N laststr 2strlst 2strtointlst
                  16strlst)
  (if (equal real 0 0.00000000000001)
    (setq 16str "0000000000000000")
    (progn
                                        ;判断符号位
      (if (> real 0)
        (setq 2str "0")
        (setq 2str "1")
      )
      (setq real (abs real))
      (SETQ N 1023)
      (WHILE (< 2 REAL)
        (SETQ REAL (/ REAL 2.0))
        (SETQ N (1+ N))
      )
      (setq 2str (strcat 2str (itoa n 2))) ;增加阶码位
      (setq real (1- real))                ;取尾数部分
      (setq laststr "")                        ;位数部分二进制初始值
      (repeat 52
        (setq real (* 2.0 real))
        (if (>= real 1)
          (progn (setq laststr (strcat laststr "1"))
                 (setq real (1- real))
          )
          (setq laststr (strcat laststr "0"))
        )
      )
      (setq 2str (strcat 2str laststr))        ;完整的64位二进制
      (setq 2strlst (string-Split 2str 4)) ;每四位分割成表
      (setq 2strtointlst (mapcar '2str-to-int 2strlst))
                                        ;每四位转换成十进制整数
      (setq 16strlst (mapcar '(lambda (X) (itoa x 16)) 2strtointlst))
                                        ;每个整数转换为16进制字符串
      (setq 16str (strcase(apply 'strcat 16strlst))) ;表中字符串按顺序合并
    )
  )
)

;长度为1的字符串16进制转10进制
(DEFUN 16TO10(str)
  (setq str(strcase str))
  (ascii "9")
  (if(> (ascii str) 57)
    (- (ascii str) 55)
    (read str)
    )
  )
;单字节字符串转10进制
(DEFUN byteto10(str)
  (setq str(strcase str))
  (if (< (strlen str) 2)(setq str (strcat "0" str)))
  (+ (* 16 (16TO10 (substr str 1 1))) (16TO10 (substr str 2 1)))
  )
;多字节字符串转10进制
(DEFUN bytesto10(str)
  (setq lst (mapcar 'byteto10 (string-Split str 2)))
  )
;单字符串前面补位0,n补位个数
(DEFUN add0str (str n)
  (setq str (strcase str))
  (while (< (strlen str) n)
    (setq str (strcat "0" str ))
  )
  str
)
;单字符串后面补位0,n补位个数
(DEFUN addstr0 (str n)
  (setq str (strcase str))
  (while (< (strlen str) n)
    (setq str (strcat  str "0"))
  )
  str
)
;两个常规字符代表一个字节,不足前面补0
(defun onebytes(str)
  (if (/= (strlen str) 2)(add0str str 2)str)
  )
;64hex2float 64位16进制字符串转双精度浮点数
;str 长度位16的字符串
;(64hex2float "405D49652BD3C361")->"117.1468"
(defun 64hex2float (str / 2lst 2str fhw zsw wsw zsm ws wswlst)
  (setq lst (mapcar '16TO10 (string-Split str 1)))
  (setq 2lst (mapcar '(lambda (X) (add0str (itoa x 2) 4)) lst))
  (setq 2str (apply 'strcat 2lst))
  (setq fhw (substr 2str 1 1))
  (setq zsw (substr 2str 2 11))
  (setq wsw (substr 2str 13 52))
  (setq zsm (- (2str-to-int zsw) 1023))
  (setq ws 0.000000000000001)
  (setq wswlst (reverse (string-split wsw 1)))
  (while wswlst
    (if        (= "1" (car wswlst))
      (setq ws (/ (1+ ws) 2.0))
      (setq ws (/ ws 2.0))
    )
    (if        (> ws 1)
      (setq ws (- ws 1))
    )
    (setq wswlst (cdr wswlst))
  )
  (if (= "1" fhw)
    (- 0 (* (+ 1 ws) (expt 2 zsm)))
    (* (+ 1 ws) (expt 2 zsm))
  )
)
;32hex2float 32位16进制字符串转双精度浮点数
;str 长度位8的字符串
;(32hex2float "42EA4B29")->"117.1468"
(defun 32hex2float (str / 2lst 2str fhw zsw wsw zsm ws wswlst)
  (setq lst (mapcar '16TO10 (string-Split str 1)))
  (setq 2lst (mapcar '(lambda (X) (add0str (itoa x 2) 4)) lst))
  (setq 2str (apply 'strcat 2lst))
  (setq fhw (substr 2str 1 1))
  (setq zsw (substr 2str 2 8))
  (setq wsw (substr 2str 10 23))
  (setq zsm (- (2str-to-int zsw) 127))
  (setq ws 0.0000001)
  (setq wswlst (reverse (string-split wsw 1)))
  (while wswlst
    (if        (= "1" (car wswlst))
      (setq ws (/ (1+ ws) 2.0))
      (setq ws (/ ws 2.0))
    )
    (if        (> ws 1)
      (setq ws (- ws 1))
    )
    (setq wswlst (cdr wswlst))
  )
  (if (= "1" fhw)
    (- 0 (* (+ 1 ws) (expt 2 zsm)))
    (* (+ 1 ws) (expt 2 zsm))
  )
)




本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?注册

x

评分

参与人数 2明经币 +2 金钱 +5 收起 理由
tigcat + 1 + 5 很给力!
tryhi + 1 赞一个!

查看全部评分

发表于 2024-7-5 17:09:13 | 显示全部楼层
  1. ;;=============================================================
  2. ;;; 程序加载后,就可以用tranf来激活一个系统隐藏的函数           
  3. ;;; 用法:(tranf "内部函数名")                                 
  4. ;;; 参数:函数名的字符串                                       
  5. ;;; 返回:T存在或者是可用的内部函数,nil不存在或则无效         
  6. ;;; 作者:highflybird                                          
  7. ;;; 例子:(tranf "get-logical-drives")                          
  8. ;;; 此程序得到网友baitang36和不死猫的大力帮助,特此致谢!      
  9. ;;; 另外借鉴了tryhi和其他网友的代码,在此一并感谢!            
  10. ;;;-------------------------------------------------------------
  11. (defun HFB-LOAD-TRANF (/ f o l s b)
  12.   (setq o (strcat (getenv "UserProfile") "\\Intern.fas"))
  13.   (if (findfile o)
  14.     (vl-file-delete o)
  15.   )
  16.   (setq        l '(70         65   83   52        45   70          73   76   69         13   49   13
  17.             49         32   36   1        36   51          51   32   48         32   36   86
  18.             58         76   80   80        0    105  110  116  101         114  110  0
  19.             108         112  112  45        115  121  109  102  117         110  45   62
  20.             97         108  0           0        57   3          0    22   36
  21.            )
  22.   )
  23.   (setq b (vlax-make-safearray 17 (cons 0 (1- (length l)))))
  24.   (vlax-safearray-fill b l)
  25.   (setq s (vlax-create-object "ADODB.Stream"))
  26.   (vlax-put s 'type 1)
  27.   (vlax-invoke s 'open)
  28.   (vlax-invoke-method s 'Write b)
  29.   (vlax-invoke s 'saveToFile o 2)
  30.   (vlax-invoke s 'close)
  31.   (vlax-release-object s)
  32.   (mapcar
  33.     'set
  34.     '(:lpp intern lpp-symfun->al)
  35.     (mapcar 'eval (load o))
  36.   )
  37.   (vl-file-delete o)
  38.   (defun tranf (s) (lpp-symfun->al (intern s :lpp)))
  39.   (tranf 'al-add-subr-name)
  40.   (mapcar
  41.     'al-add-subr-name
  42.     '(al-add-subr-name lpp-symfun->al intern tranf)
  43.   )
  44.   (if lpp-symfun->al
  45.     (princ "\n已打开内部函数转普通函数大门.\n")
  46.     (princ "\n激活内部函数转普通函数失败!\n")
  47.   )
  48. )
  49. ;激活保留函数功能的自定义函数
  50. (or lpp-symfun->al (HFB-LOAD-TRANF))

  51. ;激活itoa进制转换函数(itoa [int] [进制 int])最多32进制
  52. (tranf "itoa")

  53. ;字符串分段函数
  54. ;参数 str 类型sting
  55. ;参数 dimod 当dimod为int时,按int分割(string-Split "asfsgsb" 2)-> '( "as" "fs" gs" b")
  56. ;参数 dimod 当dimod为string时,按string 分割(string-Split "assfssgssb" "ss" )-> '( "a" "f" g" b")
  57. (defun string-Split (str dimod / str dimod n nlst)
  58.   (if (= (TYPE dimod) 'INT)
  59.     (progn
  60.       (setq n         1
  61.             nlst nil
  62.       )
  63.       (while (<= n (strlen STR))
  64.         (setq nlst (cons (substr str n dimod) nlst))
  65.         (setq n (+ n dimod))
  66.       )
  67.       (reverse nlst)
  68.     )
  69.     (progn
  70.       (while (setq n (vl-string-search dimod str))
  71.         (setq nlst (cons (substr str 1 n) nlst)
  72.               str  (substr str (+ 1 (strlen dimod) n))
  73.         )
  74.       )
  75.       (reverse (cons str nlst))
  76.     )
  77.   )
  78. )

  79. ;二进制字符串转整数
  80. ;(2str-to-int "1101")->13
  81. (defun 2str-to-int(str / n int)
  82.   (setq n (strlen str) int 0)
  83.   (while (/= str "")
  84.     (setq n (- n 1))
  85.     (if (= "1" (substr str 1 1))
  86.       (setq int (+ int (expt 2 n)))
  87.       )
  88.     (setq str (substr str 2))
  89.     )
  90.   int
  91.   )
  92. ;32float2hex单精度浮点数转16进制字符串
  93. ;real 单精度浮点数(此处用小数表示)
  94. ;(32float2hex 117.1468)->"42EA4B29"
  95. (defun 32float2hex (real / 16str 2str N laststr 2strlst 2strtointlst
  96.                   16strlst)
  97.   (if (equal real 0 0.00000000000001)
  98.     (setq 16str "00000000")
  99.     (progn
  100.                                         ;判断符号位
  101.       (if (> real 0)
  102.         (setq 2str "0")
  103.         (setq 2str "1")
  104.       )
  105.       (setq real (abs real))
  106.       (SETQ N 127)
  107.       (WHILE (< 2 REAL)
  108.         (SETQ REAL (/ REAL 2.0))
  109.         (SETQ N (1+ N))
  110.       )
  111.       (setq 2str (strcat 2str (itoa n 2))) ;增加阶码位
  112.       (setq real (1- real))                ;取尾数部分
  113.       (setq laststr "")                        ;尾数部分二进制初始值
  114.       (repeat 23;尾数位数
  115.         (setq real (* 2.0 real))
  116.         (if (>= real 1)
  117.           (progn (setq laststr (strcat laststr "1"))
  118.                  (setq real (1- real))
  119.           )
  120.           (setq laststr (strcat laststr "0"))
  121.         )
  122.       )
  123.       (setq 2str (strcat 2str laststr))        ;完整的32位二进制
  124.       (setq 2strlst (string-Split 2str 4)) ;每四位分割成表
  125.       (setq 2strtointlst (mapcar '2str-to-int 2strlst))
  126.                                         ;每四位转换成十进制整数
  127.       (setq 16strlst (mapcar '(lambda (X) (itoa x 16)) 2strtointlst))
  128.                                         ;每个整数转换为16进制字符串
  129.       (setq 16str (strcase(apply 'strcat 16strlst))) ;表中字符串按顺序合并
  130.     )
  131.   )
  132. )
  133. ;64float2hex双精度浮点数转16进制字符串
  134. ;real 双精度浮点数(此处用小数表示)
  135. ;(64float2hex 117.1468)->"405D49652BD3C361"
  136. (defun 64float2hex (real / 16str 2str N laststr 2strlst 2strtointlst
  137.                   16strlst)
  138.   (if (equal real 0 0.00000000000001)
  139.     (setq 16str "0000000000000000")
  140.     (progn
  141.                                         ;判断符号位
  142.       (if (> real 0)
  143.         (setq 2str "0")
  144.         (setq 2str "1")
  145.       )
  146.       (setq real (abs real))
  147.       (SETQ N 1023)
  148.       (WHILE (< 2 REAL)
  149.         (SETQ REAL (/ REAL 2.0))
  150.         (SETQ N (1+ N))
  151.       )
  152.       (setq 2str (strcat 2str (itoa n 2))) ;增加阶码位
  153.       (setq real (1- real))                ;取尾数部分
  154.       (setq laststr "")                        ;位数部分二进制初始值
  155.       (repeat 52
  156.         (setq real (* 2.0 real))
  157.         (if (>= real 1)
  158.           (progn (setq laststr (strcat laststr "1"))
  159.                  (setq real (1- real))
  160.           )
  161.           (setq laststr (strcat laststr "0"))
  162.         )
  163.       )
  164.       (setq 2str (strcat 2str laststr))        ;完整的64位二进制
  165.       (setq 2strlst (string-Split 2str 4)) ;每四位分割成表
  166.       (setq 2strtointlst (mapcar '2str-to-int 2strlst))
  167.                                         ;每四位转换成十进制整数
  168.       (setq 16strlst (mapcar '(lambda (X) (itoa x 16)) 2strtointlst))
  169.                                         ;每个整数转换为16进制字符串
  170.       (setq 16str (strcase(apply 'strcat 16strlst))) ;表中字符串按顺序合并
  171.     )
  172.   )
  173. )

  174. ;长度为1的字符串16进制转10进制
  175. (DEFUN 16TO10(str)
  176.   (setq str(strcase str))
  177.   (ascii "9")
  178.   (if(> (ascii str) 57)
  179.     (- (ascii str) 55)
  180.     (read str)
  181.     )
  182.   )
  183. ;单字节字符串转10进制
  184. (DEFUN byteto10(str)
  185.   (setq str(strcase str))
  186.   (if (< (strlen str) 2)(setq str (strcat "0" str)))
  187.   (+ (* 16 (16TO10 (substr str 1 1))) (16TO10 (substr str 2 1)))
  188.   )
  189. ;多字节字符串转10进制
  190. (DEFUN bytesto10(str)
  191.   (setq lst (mapcar 'byteto10 (string-Split str 2)))
  192.   )
  193. ;单字符串前面补位0,n补位个数
  194. (DEFUN add0str (str n)
  195.   (setq str (strcase str))
  196.   (while (< (strlen str) n)
  197.     (setq str (strcat "0" str ))
  198.   )
  199.   str
  200. )
  201. ;单字符串后面补位0,n补位个数
  202. (DEFUN addstr0 (str n)
  203.   (setq str (strcase str))
  204.   (while (< (strlen str) n)
  205.     (setq str (strcat  str "0"))
  206.   )
  207.   str
  208. )
  209. ;两个常规字符代表一个字节,不足前面补0
  210. (defun onebytes(str)
  211.   (if (/= (strlen str) 2)(add0str str 2)str)
  212.   )
  213. ;64hex2float 64位16进制字符串转双精度浮点数
  214. ;str 长度位16的字符串
  215. ;(64hex2float "405D49652BD3C361")->"117.1468"
  216. (defun 64hex2float (str / 2lst 2str fhw zsw wsw zsm ws wswlst)
  217.   (setq lst (mapcar '16TO10 (string-Split str 1)))
  218.   (setq 2lst (mapcar '(lambda (X) (add0str (itoa x 2) 4)) lst))
  219.   (setq 2str (apply 'strcat 2lst))
  220.   (setq fhw (substr 2str 1 1))
  221.   (setq zsw (substr 2str 2 11))
  222.   (setq wsw (substr 2str 13 52))
  223.   (setq zsm (- (2str-to-int zsw) 1023))
  224.   (setq ws 0.000000000000001)
  225.   (setq wswlst (reverse (string-split wsw 1)))
  226.   (while wswlst
  227.     (if        (= "1" (car wswlst))
  228.       (setq ws (/ (1+ ws) 2.0))
  229.       (setq ws (/ ws 2.0))
  230.     )
  231.     (if        (> ws 1)
  232.       (setq ws (- ws 1))
  233.     )
  234.     (setq wswlst (cdr wswlst))
  235.   )
  236.   (if (= "1" fhw)
  237.     (- 0 (* (+ 1 ws) (expt 2 zsm)))
  238.     (* (+ 1 ws) (expt 2 zsm))
  239.   )
  240. )
  241. ;32hex2float 32位16进制字符串转双精度浮点数
  242. ;str 长度位8的字符串
  243. ;(32hex2float "42EA4B29")->"117.1468"
  244. (defun 32hex2float (str / 2lst 2str fhw zsw wsw zsm ws wswlst)
  245.   (setq lst (mapcar '16TO10 (string-Split str 1)))
  246.   (setq 2lst (mapcar '(lambda (X) (add0str (itoa x 2) 4)) lst))
  247.   (setq 2str (apply 'strcat 2lst))
  248.   (setq fhw (substr 2str 1 1))
  249.   (setq zsw (substr 2str 2 8))
  250.   (setq wsw (substr 2str 10 23))
  251.   (setq zsm (- (2str-to-int zsw) 127))
  252.   (setq ws 0.0000001)
  253.   (setq wswlst (reverse (string-split wsw 1)))
  254.   (while wswlst
  255.     (if        (= "1" (car wswlst))
  256.       (setq ws (/ (1+ ws) 2.0))
  257.       (setq ws (/ ws 2.0))
  258.     )
  259.     (if        (> ws 1)
  260.       (setq ws (- ws 1))
  261.     )
  262.     (setq wswlst (cdr wswlst))
  263.   )
  264.   (if (= "1" fhw)
  265.     (- 0 (* (+ 1 ws) (expt 2 zsm)))
  266.     (* (+ 1 ws) (expt 2 zsm))
  267.   )
  268. )

评分

参与人数 1明经币 +1 收起 理由
tryhi + 1

查看全部评分

发表于 2024-7-9 18:19:19 | 显示全部楼层
这么好的函数居然没评论
您需要登录后才可以回帖 登录 | 注册

本版积分规则

小黑屋|手机版|CAD论坛|CAD教程|CAD下载|联系我们|关于明经|明经通道 ( 粤ICP备05003914号 )  
©2000-2023 明经通道 版权所有 本站代码,在未取得本站及作者授权的情况下,不得用于商业用途

GMT+8, 2024-11-25 04:21 , Processed in 0.183383 second(s), 28 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表