技術士試験の問題によく IEEE 単精度浮動小数点数の計算問題が出てくるので、
Scheme で実装してみました。
情報工学部門の技術士を目指すなら、毎回計算してないでプログラム書いて解けよ!
と思いますよね?
でも試験は頭で解かないとダメですーwww
面倒くさいなもうwwwwwwwww
(define nil '()) (define (digit->integer c) (- (char->integer c) (char->integer #\0))) ;; (define (number->bns num) (format #f "~32,'0b" num)) (define (bns->float bns) (let ((s (get-s bns)) (e (get-e bns)) (m (get-m bns))) (* s m (expt 2 (- e 127))))) (define (get-s bns) (let ((val (string->number (substring bns 0 1) 2))) (if (= val 0) 1 -1))) (define (get-e bns) (string->number (substring bns 1 9) 2)) (define (get-m bns) (bns->binary (substring bns 9 32))) (define (bns->binary bns) (define (iter lst k val) (if (null? lst) val (iter (cdr lst) (/ k 2) (if (= (car lst) 1) (+ val k) val)))) (iter (map digit->integer (string->list bns)) 0.5 1)) (define (optimize-hex f) (let* ((v (if (< f 0) (* -1 f) f)) (s (string-split (number->string v) ".")) (i (integer-part (car s))) (d (decimal-part (cdr s))) (e (- (string-length i) 1)) (m (substring (string-append (substring i 1 (+ e 1)) d) 0 23))) (cons (+ 127 e) m))) (define (integer-part str) (format #f "~b" (string->number str))) (define (decimal-part str) (if (null? str) (number->bns 0) (str->bns (car str)))) (define (str->bns str) (define (iter i k v bns) (if (> i 23) bns (if (>= v k) (iter (+ i 1) (/ k 2) (- v k) (string-append bns "1")) (iter (+ i 1) (/ k 2) v (string-append bns "0"))))) (iter 1 0.5 (string->number (string-append "0." str)) "")) (define (bns->hex bns) (define (iter lst hex) (if (null? lst) hex (iter (cddddr lst) (string-append hex (format #f "~x" (+ (* 8 (car lst)) (* 4 (cadr lst)) (* 2 (caddr lst)) (cadddr lst))))))) (iter (map digit->integer (string->list bns)) "")) ;; IEEE 標準形式(単精度) 16->2 進数変換 (define (hex->float hex) (bns->float (number->bns hex))) ;; IEEE 標準形式(単精度) 2->16 進数変換 (define (float->hex f) (let* ((s (if (< f 0) "1" "0")) (h (optimize-hex f)) (e (car h)) (m (cdr h))) (bns->hex (string-append s (format #f "~8,'0b" e) m))))
難しい事は何もやってません。計算してみます。
gosh> (float->hex (* (hex->float #x40a80000) (hex->float #xc0300000))) "c1670000"
結果が文字列になっていて Scheme の 16 進表現と違いますが・・・
漢は細かいこと気にしない!w 計算結果が合っていれば良いのです。(手抜き