; logarithm tables
(define (range . args)
(case (length args)
((1) (range 0 (car args) (if (negative? (car args)) -1 1)))
((2) (range (car args) (cadr args) (if (< (car args) (cadr args)) 1 -1)))
((3) (let ((le? (if (negative? (caddr args)) >= <=)))
(let loop ((x(car args)) (xs '()))
(if (le? (cadr args) x)
(reverse xs)
(loop (+ x (caddr args)) (cons x xs))))))
(else (error 'range "unrecognized arguments"))))
(define (pr4 x)
(let* ((x (inexact->exact (round (* x 10000))))
(s (number->string x)))
(if (< x 1000) (set! s (string-append "0" s)))
(if (< x 100) (set! s (string-append "0" s)))
(if (< x 10) (set! s (string-append "0" s)))
s))
(define (pr2 x)
(let ((s (number->string x)))
(if (< x 10) (set! s (string-append " " s)))
s))
(define (log10 x) (/ (log x) (log 10)))
(define (average xs) (/ (apply + xs) (length xs)))
(define (display-header)
(display " ")
(do ((j 0 (+ j 1))) ((= j 10))
(display " ")
(display j))
(display " ")
(do ((j 1 (+ j 1))) ((= j 10))
(display " ")
(display j))
(newline))
(define (display-bar)
(display "-- ")
(do ((j 0 (+ j 1))) ((= j 10))
(display " ") (display "----"))
(display " ")
(do ((j 1 (+ j 1))) ((= j 10))
(display " ") (display "--"))
(newline))
(define (log-average-interp i k)
(define (add-on j)
(- (* (log10 (/ (+ i (* j 10) k) 1000.0)) 10000)
(* (log10 (/ (+ i (* j 10)) 1000.0)) 10000)))
(inexact->exact (round (average (map add-on (range 10))))))
(define (log-display-interp i)
(display " ")
(do ((k 1 (+ k 1))) ((= 10 k))
(display " ")
(display (pr2 (log-average-interp i k)))))
(define (log-display-line i)
(do ((j 0 (+ j 10))) ((= 100 j))
(display " ")
(display (pr4 (log10 (/ (+ i j) 1000)))))
(log-display-interp i))
(define (log-display-table)
(display-header)
(do ((i 1000 (+ i 100))) ((= 10000 i))
(if (zero? (modulo i 1000)) (display-bar))
(display (/ i 100))
(display " ")
(log-display-line i)
(newline)))
(define (alog-average-interp i k)
(define (add-on j)
(- (* (expt 10 (+ 1 (/ (+ i (* j 10) k) 10000))) 100)
(* (expt 10 (+ 1 (/ (+ i (* j 10)) 10000))) 100)))
(inexact->exact (round (average (map add-on (range 10))))))
(define (alog-display-interp i)
(display " ")
(do ((k 1 (+ k 1))) ((= 10 k))
(display " ")
(display (pr2 (alog-average-interp i k)))))
(define (alog-display-line i)
(do ((j 0 (+ j 10))) ((= 100 j))
(display " ")
(display (pr4 (/ (expt 10 (+ 1 (/ (+ i j) 10000))) 100))))
(alog-display-interp i))
(define (alog-display-table)
(display-header)
(do ((i 1000 (+ i 100))) ((= 10000 i))
(if (zero? (modulo i 1000)) (display-bar))
(display (/ i 100))
(display " ")
(alog-display-line i)
(newline)))
(display "Logarithms") (newline) (newline)
(log-display-table) (newline) (newline) (newline)
(display "Anti-Logarithms") (newline) (newline)
(alog-display-table)