[Haskell-beginners] Re:Re Puzzling type erros

Logesh Pillay lpillay at webafrica.org.za
Mon Aug 25 01:14:12 EDT 2008


Thanks, chaps,  for the replies to my over-hasty post.  I should have 
checked with a power of 10 value for scale which would have pointed to 
types to logBase  as the error.

Andrew's comment about floating point not having unlimited precision 
clears up a glitch that using fromInteger introduces.  If you use it to 
typecast b, it appears to set a limit to the number of digits it 
generates.  It only gives you 308 or so even if you set scale equal to 
1000, say.

If you test b against  10^scale, you get  as many digits as you wish.

Logesh Pillay

> Message: 10
> Date: Sun, 24 Aug 2008 21:07:53 -0400
> From: ajb at spamcop.net
> Subject: Re: [Haskell-beginners] Puzzling type error
> To: beginners at haskell.org
> Message-ID: <20080824210753.42c5u3ihw444gc8o-nwo at webmail.spamcop.net>
> Content-Type: text/plain;	charset=ISO-8859-1;	DelSp="Yes";
> 	format="flowed"
>
> G'day all.
>
> Quoting Daniel Fischer <daniel.is.fischer at web.de>:
>
>   
>> > The good fix is to insert calls to the apprpriate conversion function where
>> > necessary, for example
>> >
>> > sqRoot n scale = sqRoot' (5*n) 5
>> >   where
>> >   sqRoot' a b
>> >     | floor (logBase 10 $ fromIntegral b) >= scale = div b 10
>> >     | a >= b    = sqRoot' (a-b) (b+10)
>> >     | otherwise = sqRoot' (a*100) ((100 * (div b 10)) + (mod b 10))
>>     
>
> The problem here is that floating-point numbers do not have arbitrary
> precision, whereas Integers do.  For very large numbers, the
> conversion might not be possible.
>
> Option #1:
>
> sqRoot n scale = sqRoot' (5*n) 5
>    where
>    sqRoot' a b
>      | b >= invScale = div b 10
>      | a >= b    = sqRoot' (a-b) (b+10)
>      | otherwise = sqRoot' (a*100) ((100 * (div b 10)) + (mod b 10))
>    invScale = 10^scale
>
> Option #2:
>
> sqRoot n scale = sqRoot' (5*n) 5
>    where
>    sqRoot' a b
>      | length (show b) >= scale = div b 10  -- May be an off-by-one error here.
>      | a >= b    = sqRoot' (a-b) (b+10)
>      | otherwise = sqRoot' (a*100) ((100 * (div b 10)) + (mod b 10))
>
> Sadly, option #2 (and option #3, not shown, which is essentially to
> implement your own integer-only floor-log-base-10) destroys the
> pretty "mostly subtraction only" property of the algorithm.
>
> Cheers,
> Andrew Bromage
>   



More information about the Beginners mailing list