1

我想把一个很大的数字,实际上是从 unix 纪元时间算起的以秒为单位的当前时间,变成一个十六进制字符串。

我很久以前就破解了一些代码,(我认为)它适用于早期版本的 emacs,但它在我现在使用的 emacs 23 上不再适用(可能是我搞砸了代码)。

我写它的时候的困难是这个数字很大,要作为某些函数的一个参数来处理,所以我必须把它分开,做一些事情,然后把它们放在一起。例如,如果你给 一个很大的数字string-to-number,即使我想要一个整数,它也会返回一个浮点数。

任何人都可以建议重写它吗?

以下是我编写的损坏代码。它不起作用,但可能会让您了解我正在尝试做什么。首先,这些都是下面使用的子程序:

(defun seconds-since-origin ()
    (string-to-number (concat
        (number-to-string (- (string-to-number
            (substring (format-time-string "%s") 0 5)
         ) 10000))
    (substring (format-time-string "%s") 5)
)))

(defun hexatridecimal (decimal)
(concat
    (let ((quotient (/ decimal 36)))    (if (> quotient 35)
        (hexatridecimal quotient)
        (hexatridecimal-digit quotient)
    ))
    (hexatridecimal-digit (% decimal 36))
))

(defun hexatridecimal-digit (number)
    (nth number (list
"0" "1" "2" "3" "4" "5" "6" "7" "8" "9" "a" "b" "c" "d" "e" "f" "g" "h" "i" "j"
    "k" "l" "m" "n" "o" "p" "q" "r" "s" "t" "u" "v" "w" "x" "y" "z"))
)

以下将是将被调用的主要函数:

(hexatridecimal (seconds-since-origin))
4

1 回答 1

2

使用 64 位 Emacs(可以像您使用的那样处理整数),进行以下更改:

(defun seconds-since-origin ()
  (string-to-number (format-time-string "%s")))

(defun hexatridecimal (decimal)
  (let ((quotient (/ decimal 36))
        (remainder (% decimal 36)))
    (concat 
     (if (> quotient 0)
         (hexatridecimal quotient)
       "")
     (hexatridecimal-digit remainder))))

注意:这确实假设 64 位 Emacs比 32 位构建具有更多用于大整数的位。

如果您想在 32 位 Emacs 上工作,您可以使用calc的 big-int 功能为您计算,并适当地调整代码。

编辑添加: 这是使用calcbignum 功能的版本:

(require 'calc)
(require 'calc-ext)
(defun seconds-since-origin ()
  (math-read-number-simple (format-time-string "%s")))
(defun hexatridecimal (decimal-bignum)
  (let* ((q-r (math-idivmod decimal-bignum 36))
     (quotient (car q-r))
     (remainder (cdr q-r)))
(concat 
 (if (math-lessp 0 quotient)
     (hexatridecimal quotient)
   "")
 (hexatridecimal-digit remainder))))
于 2011-03-21T22:53:28.393 回答