Re:Re Puzzling type erros

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
1 message Options
Reply | Threaded
Open this post in threaded view
|

Re:Re Puzzling type erros

Logesh Pillay-3
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: [hidden email]
> Subject: Re: [Haskell-beginners] Puzzling type error
> To: [hidden email]
> Message-ID: <[hidden email]>
> Content-Type: text/plain; charset=ISO-8859-1; DelSp="Yes";
> format="flowed"
>
> G'day all.
>
> Quoting Daniel Fischer <[hidden email]>:
>
>  
>> > 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
>