# [Haskell-cafe] [Solved] rounding errors with real numbers.

Matthias Fischmann fis at wiwi.hu-berlin.de
Sun Feb 26 11:31:46 EST 2006

```On Sun, Feb 26, 2006 at 01:00:54PM +0000, Chris Kuklewicz wrote:
> To: Matthias Fischmann <fis at wiwi.hu-berlin.de>
> From: Chris Kuklewicz <haskell at list.mightyreason.com>
> Date: Sun, 26 Feb 2006 13:00:54 +0000
> Subject: Re: [Haskell-cafe] rounding errors with real numbers.
>
> Your solution works, but is slightly wasteful with (repair) traversing
> the whole list again.  Here is a slightly more efficient expression:
>
> -- Precondition: The first parameter (xs) is sorted (ascending) :
> --                 assert (all (zipWith (<=) (xs, tail xs)))
> --               low' < high'
> --               low  < high
> normInterval :: [Double] -> Double -> Double -> [Double]
> normInterval xs low high = let low' = head xs; high' = last xs;
>                                scale = (high-low)/(high'-low')
>                                middle = init (tail xs)
>                            in (low : [scale*(x-low')+low) | x <-middle])++[high]

hi chris,

i like this code better, too.  slightly better still, because of fewer
typos:

normInterval :: [Double] -> Double -> Double -> [Double]
normInterval ps lower upper = assert check ([lower] ++ [ stretch * (p - oldLower) + lower | p <- middle ] ++ [upper])
where
check = lower < upper && oldLower < oldUpper && (and (zipWith (<=) ps (tail ps)))
oldUpper = last ps
stretch = (upper - lower) / (oldUpper - oldLower)
middle = init (tail ps)

but then i'll just take this as the best solution.

thanks,
matthias
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 189 bytes
Desc: Digital signature