16進数を10進数に戻す関数・改
16進数を10進数に戻す関数 - Shammerismで、16進数の文字列表記を10進の数字にするものを作成したが、少し手を加えて数のリストとcharacterのリストにも対応させることにする。
リスト内の要素が全て同一タイプかを判定する関数
たとえば、(0 1 2 3) や (#\a #\a #\a) のようなものを判定したい。
(defun typelistp (l type) (if (null l) t (and (typep (car l) type) (typelistp (cdr l) type))))
これはこんな風に使える。
? (typelistp '(0 1 2 3) 'number) T ? (typelistp '(0 1 2 "aaa") 'number) NIL ? (typelistp '(#\a #\a #\a) 'character) T ? (typelistp '(#\a #\a "a") 'character) NIL ?
hex2dec拡張
16進数を10進数に戻す関数 - Shammerismのバージョンではstringpのみの判定だったが、上記を使って以下のように変更。
(defun hex2dec (x) (labels ((typelistp (l type) (if (null l) t (and (typep (car l) type) (typelistp (cdr l) type))))) (let ((result 0) (base 1)) (cond ((stringp x) (dolist (c (reverse (coerce x 'list))) (cond ((char-equal c #\A) (setf result (+ result (* base 10)))) ((char-equal c #\B) (setf result (+ result (* base 11)))) ((char-equal c #\C) (setf result (+ result (* base 12)))) ((char-equal c #\D) (setf result (+ result (* base 13)))) ((char-equal c #\E) (setf result (+ result (* base 14)))) ((char-equal c #\F) (setf result (+ result (* base 15)))) (t (setf result (+ result (* base (parse-integer (string c))))))) (setf base (* base 16)))) ((typelistp x 'number) (dolist (c (reverse x)) (setf result (+ result (* base c))) (setf base (* base 16)))) ((typelistp x 'character) (setf result (hex2dec (coerce x 'string)))) (t (setf result x))) result)))
char-equal を使えば、大文字小文字関係なく比較してくれるのでこれを使うことにした。実行結果は以下。
? (hex2dec '(1 2 3 4)) 4660 ? (format nil "~d" #x1234) "4660" ? (hex2dec '(#\a #\b)) 171 ? (format nil "~d" #xab) "171" ?