<code style="font-family: courier new,monospace;">(define (ilog b n)<br> (let loop ((n n) (i -1))<br> (if (zero? n) i<br> (loop (quotient n b) (+ i 1)))))<br><br>(ilog 10 #e1000e1000000) => 1000003<br></code><br style="font-family: courier new,monospace;">
<div class="gmail_quote"><span style="font-family: courier new,monospace;">It does take a while....</span><br><br>On Thu, Nov 5, 2009 at 5:04 AM, Jos Koot <span dir="ltr"><<a href="mailto:jos.koot@telefonica.net" target="_blank">jos.koot@telefonica.net</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">
<div bgcolor="#ffffff"><font size="2" face="Courier New">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:<br><br>(define log10 (inexact->exact (log 10)))<br>(define
(order-of-magnitude q) (floor (/ (inexact->exact (log q))
log10)))<br><br>However, due to inexactness of function log we find:<br><br>(/
(inexact->exact (log #e1000e1000000)) log10) --> close to but sligtly less
than 1000003<br><br>and hence:<br><br>(order-of-magnitude #e1000e1000000) ;
--> 1000002 <br><br>The wanted answer is 1000003. So I did the
following:<br><br>(define order-of-magnitude<br> (let*<br> ((log10
(inexact->exact (log 10)))<br> (10log (λ (q) (/
(inexact->exact (log q)) log10))))<br> (λ (q)<br> (unless
(and (rational? q) (exact? q) (positive? q))<br>
(raise-type-error 'magnitude "positive exact rational number"
q))<br> (let* ((m (floor (10log q))) (k (expt 10
m)))<br> ; From now on all arithmetic operations and their
operands are exact.<br> (let loop ((m m) (lower (* k 1/10))
(middle k) (upper (* k 10)))<br>
(cond<br> ((<= q lower) (loop (sub1 m) (* lower
1/10) lower middle))<br> ((>= q upper) (loop
(add1 m) middle upper (* upper 10)))<br> (else
m)))))))<br><br>(order-of-magnitude #e1000e1000000) ; -->
1000003<br><br>However, this seems rather complicated. Does someone have or know
of a simpler and faster function for this purpose?<br><br>Thanks,
Jos</font></div>
<br>_________________________________________________<br>
For list-related administrative tasks:<br>
<a href="http://list.cs.brown.edu/mailman/listinfo/plt-scheme" target="_blank">http://list.cs.brown.edu/mailman/listinfo/plt-scheme</a><br>
<br></blockquote></div><br>