Thanks, guys! It looks at first glance as if the code Thorkil posted is similar to mine (grow comparison number in steps of 2 in the exponent, then binary-search to get the exact exponent), while Stefan&#39;s version is more similar to the walk-the-list idea I had in mind. I&#39;ll play with both of these when I get a chance...<br>
<br>Uwe<br><br><div class="gmail_quote">On Feb 10, 2008 10:44 PM, Thorkil Naur &lt;<a href="mailto:naur@post11.tele.dk">naur@post11.tele.dk</a>&gt; wrote:<br><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">
Hello,<br><br>If the standard libraries provide such a function, I haven&#39;t found it. I must<br>admit that I haven&#39;t studied your code in detail. I usually do as follows for<br>integer logarithms, shamelessly stolen from the Haskell report:<br>
<br>&gt; &nbsp; -- Integer log base (c.f. Haskell report 14.4):<br>&gt;<br>&gt; &nbsp; imLog :: Integer-&gt;Integer-&gt;Integer<br>&gt; &nbsp; imLog b x<br>&gt; &nbsp; &nbsp; = if x &lt; b then<br>&gt; &nbsp; &nbsp; &nbsp; &nbsp; 0<br>&gt; &nbsp; &nbsp; &nbsp; else<br>&gt; &nbsp; &nbsp; &nbsp; &nbsp; let<br>
&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; l = 2 * imLog (b*b) x<br>&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; doDiv x l = if x &lt; b then l else doDiv (x`div`b) (l+1)<br>&gt; &nbsp; &nbsp; &nbsp; &nbsp; in<br>&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; doDiv (x`div`(b^l)) l<br><br>Best regards<br>Thorkil<br><div><div></div>
<div class="Wj3C7c"><br><br>On Monday 11 February 2008 07:15, Uwe Hollerbach wrote:<br>&gt; Hello, haskellers,<br>&gt;<br>&gt; Is there a fast integer base-2 log function anywhere in the standard<br>&gt; libraries? I wandered through the index, but didn&#39;t find anything that<br>
&gt; looked right. I need something that&#39;s more robust than logBase, it<br>&gt; needs to handle numbers with a few to many thousands of digits. I<br>&gt; found a thread from a couple of years ago that suggested there was no<br>
&gt; such routine, and that simply doing &quot;length (show n)&quot; might be the<br>&gt; best. That seems kind of... less than elegant. I&#39;ve come up with a<br>&gt; routine, shown below, that seems reasonably fast (a few seconds of CPU<br>
&gt; time for a million-bit number, likely adequate for my purposes), but<br>&gt; it seems that something with privileged access to the innards of an<br>&gt; Integer ought to be even much faster -- it&#39;s just a simple walk along<br>
&gt; a list (array?) after all. Any pointers? Thanks!<br>&gt;<br>&gt; Uwe<br>&gt;<br>&gt; &gt; powi :: Integer -&gt; Integer -&gt; Integer<br>&gt; &gt; powi b e | e == 0 &nbsp; &nbsp;= 1<br>&gt; &gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;| e &lt; 0 &nbsp; &nbsp; = error &quot;negative exponent in powi&quot;<br>
&gt; &gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;| even e &nbsp; &nbsp;= powi (b*b) (e `quot` 2)<br>&gt; &gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;| otherwise = b * (powi b (e - 1))<br>&gt;<br>&gt; &gt; ilog2 :: Integer -&gt; Integer<br>&gt; &gt; ilog2 n | n &lt; 0 &nbsp; &nbsp; &nbsp;= ilog2 (- n)<br>&gt; &gt; &nbsp; &nbsp; &nbsp; &nbsp; | n &lt; 2 &nbsp; &nbsp; &nbsp;= 1<br>
&gt; &gt; &nbsp; &nbsp; &nbsp; &nbsp; | otherwise &nbsp;= up n (1 :: Integer)<br>&gt; &gt; &nbsp; where up n a = if n &lt; (powi 2 a)<br>&gt; &gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; then bin (quot a 2) a<br>&gt; &gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; else up n (2*a)<br>&gt; &gt; &nbsp; &nbsp; &nbsp; &nbsp; bin lo hi = if (hi - lo) &lt;= 1<br>
&gt; &gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;then hi<br>&gt; &gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;else let av = quot (lo + hi) 2<br>&gt; &gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; in if n &lt; (powi 2 av)<br>&gt; &gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; then bin lo av<br>
&gt; &gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; else bin av hi<br>&gt;<br>&gt; (This was all properly aligned when I cut&#39;n&#39;pasted; proportional fonts<br>&gt; might be messing it up here.)<br></div></div>&gt; _______________________________________________<br>
&gt; Haskell-Cafe mailing list<br>&gt; <a href="mailto:Haskell-Cafe@haskell.org">Haskell-Cafe@haskell.org</a><br>&gt; <a href="http://www.haskell.org/mailman/listinfo/haskell-cafe" target="_blank">http://www.haskell.org/mailman/listinfo/haskell-cafe</a><br>
&gt;<br></blockquote></div><br>