# [plt-scheme] order of magnitude

(define (ilog b n)
(let loop ((n n) (i -1))
(if (zero? n) i
(loop (quotient n b) (+ i 1)))))
(ilog 10 #e1000e1000000) => 1000003
It does take a while....
On Thu, Nov 5, 2009 at 5:04 AM, Jos Koot <jos.koot at telefonica.net> wrote:
>* Some browsing did not lead me to finding a function that accepts an exact
*>* positive rational number and returns its order of magnitude (an exact
*>* integer number) Something like:
*>*
*>* (define log10 (inexact->exact (log 10)))
*>* (define (order-of-magnitude q) (floor (/ (inexact->exact (log q)) log10)))
*>*
*>* However, due to inexactness of function log we find:
*>*
*>* (/ (inexact->exact (log #e1000e1000000)) log10) --> close to but sligtly
*>* less than 1000003
*>*
*>* and hence:
*>*
*>* (order-of-magnitude #e1000e1000000) ; --> 1000002
*>*
*>* The wanted answer is 1000003. So I did the following:
*>*
*>* (define order-of-magnitude
*>* (let*
*>* ((log10 (inexact->exact (log 10)))
*>* (10log (λ (q) (/ (inexact->exact (log q)) log10))))
*>* (λ (q)
*>* (unless (and (rational? q) (exact? q) (positive? q))
*>* (raise-type-error 'magnitude "positive exact rational number" q))
*>* (let* ((m (floor (10log q))) (k (expt 10 m)))
*>* ; From now on all arithmetic operations and their operands are exact.
*>* (let loop ((m m) (lower (* k 1/10)) (middle k) (upper (* k 10)))
*>* (cond
*>* ((<= q lower) (loop (sub1 m) (* lower 1/10) lower middle))
*>* ((>= q upper) (loop (add1 m) middle upper (* upper 10)))
*>* (else m)))))))
*>*
*>* (order-of-magnitude #e1000e1000000) ; --> 1000003
*>*
*>* However, this seems rather complicated. Does someone have or know of a
*>* simpler and faster function for this purpose?
*>*
*>* Thanks, Jos
*>*
*>* _________________________________________________
*>* For list-related administrative tasks:
*>* http://list.cs.brown.edu/mailman/listinfo/plt-scheme
*>*
*>*
*-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.racket-lang.org/users/archive/attachments/20091105/f6912c42/attachment.html>