Hello, consider the following: Main> :version -- Hugs Version February 2001 Main> logBase 2 (fromInteger 32768) -- compute ld 2^15 15.0 Main> truncate 15.0 15 Main> floor 15.0 15 Main> floor (logBase 2 (fromInteger 32768)) -- should be == floor 15.0 14 Main> truncate (logBase 2 (fromInteger 32768)) -- should be == truncate 15.0 14 I can reproduce this with 8192 and 32768. To cut it short: (truncate (logBase 2 (fromInteger 2^a))) != a ; a=13 & a=15 Looks a little weird to me, but I'm a Haskell beginner, so possibly I just encountered an "It's not a bug, it's a feature" situation here. Sorry if this is the case. Thanks in advance, Thorsten Stocksmeier
Thorsten Stocksmeier
14
Rounding error I suspect. Prelude> logBase 2 (fromInteger 32768) - 15.0 -9.53674e-07 -- Alastair Reid alastair@reid-consulting-uk.ltd.uk Reid Consulting (UK) Limited http://www.reid-consulting-uk.ltd.uk/alastair/
Hi Alastair, thanks for your reply! Main> floor (logBase 2 (fromInteger 32768)) -- should be == floor 15.0
14
Rounding error I suspect.
Prelude> logBase 2 (fromInteger 32768) - 15.0 -9.53674e-07
Okay, but is that my fault or hugs'? Independent of that: Is there a workaround? Before logBase I used log n / log 2 as a simulation of logBase 2. Still have to find out whether this solves the problem. (well maybe logBase *is* in fact log/log - must stick my nose into the prelude this afternoon) Sincerely, Thorsten
At 08:08 +0200 2002/09/30, Thorsten Stocksmeier wrote:
Main> floor (logBase 2 (fromInteger 32768)) -- should be == floor 15.0
14
Rounding error I suspect.
Prelude> logBase 2 (fromInteger 32768) - 15.0 -9.53674e-07
Okay, but is that my fault or hugs'?
Any code that treats floating point numbers as though they are exact numbers is faulty.
Independent of that: Is there a workaround? Before logBase I used log n / log 2 as a simulation of logBase 2. Still have to find out whether this solves the problem. (well maybe logBase *is* in fact log/log - must stick my nose into the prelude this afternoon)
If you need to compare floating point numbers x, y, introduce a small epsilon > 0, and write abs(x - y) < epsilon instead of x == y. If you need them to be exact integers, make a roundoff. Etc. Hans Aberg
Alastair:
Rounding error I suspect.
Thorsten Stocksmeier
Okay, but is that my fault or hugs'?
Rather than assign blame, I think I'll assign homework. http://citeseer.nj.nec.com/goldberg91what.html This computer surveys article which discusses issues of accuracy and the like in floating point arithmetic. I's well worth reading if you haven't read it before. Another detail worth being aware of is that Hugs uses single precision arithmetic for both Float and Double.
Independent of that: Is there a workaround? Before logBase I used log n / log 2 as a simulation of logBase 2. Still have to find out whether this solves the problem. (well maybe logBase *is* in fact log/log - must stick my nose into the prelude this afternoon)
If you want a log_2 function of type Int->Int, I'd write the obvious recursive function. (Or the less obvious one-liner using iterate, takeWhile and length.) If speed is very important, I'd probably crack open some volume of Knuth's Art of Computer Programming which almost certainly has a more cunniung algorithm. -- Alastair Reid alastair@reid-consulting-uk.ltd.uk Reid Consulting (UK) Limited http://www.reid-consulting-uk.ltd.uk/alastair/
participants (3)
-
Alastair Reid -
Hans Aberg -
Thorsten Stocksmeier