狂刀lxx 发表于 2011-5-11 00:15:54

一个包括进制任意转换的函数

进制转换函数大家看得很多了吧,这个有什么特别呢?
所有常用进制的转换都写在了“一个函数”里! 你再也不必写 2to8, 8to16, 16to2.....这么多的函数了

;; 进制转换函数--专辑
;| (x!2n num from) = from 进制数值转十进制----by lxx.2005.5 ok!
参数:
      num =要转换的数值
      from = 数值,表示要转换的数值的进制类型. 取值:2,8,16
返回: 转换进制后的字符串/数值.
说明: 1. 支持 类型自动识别,返回结果类型同要转换的数值类型,注意num前面要加'.
      2. 支持非标准进制!
测试: (x!2n "9e" 16);;-> "158"
      (x!2n '9e 16)-> 158
      (x!2n '9E 16)-> 158
      (x!2n 9E 16)-> 6197 (错误,数值前需加')
      (x!2n "64" 8);; -> "52"
      (x!2n '64 8)-> 52
      (x!2n "100101" 2);;-> "37"
      (x!2n '100101 2);;-> 37
      (x!2n 100101 2) -> 37
|;
(defun x!2n(num from / $key lst i end)
(if (not(= 'STR (type num)))
    (setq num (vl-princ-to-string num) $key T)
    (setq $key nil)
)
(setq lst (mapcar '(lambda (x)(if (< x 58)(- x 48)(- x 55)))
      (vl-string->list (strcase num)))
      i -1)
(setq end (apply '+ (mapcar '(lambda (x) (* x (expt from (setq i (1+ i)))))(reverse lst))))
(if $key end (itoa end) )
)

;| (x!n2 num to) = 十进制转bas进制 -v2.0-----------by lxx.2005.10 ok!
参数:
      num =要转换的数值
      to= 数值,表示要转换成的数值的进制类型. 如:2,8,16
返回: 转换进制后的字符串/数值.
说明: 1. 支持 类型自动识别,返回结果类型同要转换的数值类型.
      2. 支持非标准进制!
测试:
;; 支持 类型自动识别. 字符串类型转换结果为字符串,符号or数字类型结果为符号or数字.
(x!n2 "45" 16) -> "2D"
(x!n2 '45 16) -> 2D
(x!n2 45 16) -> 2D
(x!n2 "19" 2) -> "2011"
(x!n2 '19 2)-> 2011
(x!n2 "29" 8);->"35"
;; 支持非标准进制!
(x!n2 29 7);->41
|;
(defun x!n2 (num to / lst $key end)
(if (= 'STR (type num))
    (setq num (atoi num) $key T)
)
(while (and (setq lst (cons (rem num to) lst))
            (> (setq num (fix (/ num to))) to)))
(setq lst (cons num lst)
lst (mapcar '(lambda(x)(if (<= x 9)(chr(+ 48 x))(chr(+ 55 x)))) lst))
(setq end (apply 'strcat lst))
(if $key end (read end))
)
;| (x!x num from to) = 进制任意转换---ok!---by lxx.2005.10
参数:
      num =要转换的数值
      from = 数值,表示要转换的数值的进制类型. 如:2,8,16
      to   = 数值,表示要转换成的数值的进制类型. 如:2,8,16
返回: 转换进制后的字符串/数值.
说明: 1. 支持 类型自动识别,返回结果类型同要转换的数值类型.
      2. 支持非标准进制!
      3. 合并以上两个函数而成.
测试:
(x!x "3a" 16 2) -> "111010"
(x!x '3a 16 2) -> 111010
(x!x '3a 16 12) ->4A ;;16进制转12进制.
(x!x '33 4 7) -> 21 ;; 4进制转7进制. 33@4=15@10=21@7.
|;
(defun x!x (num from to)
(cond
    ((and (= 10 from)(= 10 to))num)
    ((= 10 from)(x!n2 num to))
    ((= 10 to)(x!2n num from))
    (T (x!n2 (x!2n num from) to))
)
)

cnks 发表于 2011-5-11 00:37:13

支持一下刀

zhulei 发表于 2011-5-11 01:23:32

研究研究。

zhongys 发表于 2011-5-11 03:31:03

461045462 发表于 2011-5-11 09:16:39

谢谢楼主的分享
收藏了,下来学习领会
谢谢

saiko008 发表于 2011-5-11 09:54:03

pslstar 发表于 2011-12-23 00:57:28

好东西,谢谢分享啊

yxp 发表于 2013-5-2 06:23:57

狂刀兄的程序不错,美中不足还有点bug
(x!x 1250 10 16)返回 400.0
(x!x 1251 10 16)返回 4000.0
(x!x "1250" 10 16) 返回 "4E2"
(x!x "1251" 10 16) 返回 "4E3"

另外如果转换的数据量太大,会出现“8进制读取错误”的提示,再运行一次,却又好了,所以程序运行有些不稳定。

lanjqka 发表于 2013-12-19 17:12:53

楼主太好了 正在找这个
$(x!N2 158 2)
$2011110
条件 (> (setq num (fix (/ num to))) to))) 改成 (>= (setq num (fix (/ num to))) to)))
$(x!N2 158 2)
$10011110

lanjqka 发表于 2013-12-20 11:31:09

不足一位的转换要先判断num为0
(if (not (zerop num)) (setq lst (cons num lst))
页: [1]
查看完整版本: 一个包括进制任意转换的函数