[Haskell-beginners] How to improve the accuracy of floating point calculation?

Mateusz Kowalczyk fuuzetsu at fuuzetsu.co.uk
Wed Feb 6 02:07:54 CET 2013


We just figured it out over here. The short version is that the 0.1 and
0.2 just happen to round pretty well (to what looks perfect to a human)
while other figures don't. This can be easily represented by forcing a
[Float] type for lower precision as opposed to the default double precision:
*Main> [0.1, 0.2 .. 1] :: [Float]
[0.1,0.2,0.3,0.40000004,0.50000006,0.6000001,0.7000001,0.80000013,0.90000015,1.0000002]

Above we can easily see that with a float the errors compound so much
that the numbers no longer round to a human-friendly representation.

This can also be shown with doubles: the 0.1 was displayed as 0.1
because it just happened to be fairly precise. Start compounding errors
early enough and it no longer rounds so nicely:
[-0.5,-0.4,-0.30000000000000004,-0.20000000000000007,-0.10000000000000009,-1.1102230246251565e-16,9.999999999999987e-2,0.19999999999999984,0.2999999999999998,0.3999999999999998,0.4999999999999998]

You can see just how much precision we lost at mid-point by looking at
what should be 0.

Thanks

On 06/02/13 00:47, Mateusz Kowalczyk wrote:
> I thought that KC was asking why is 0.5 not displayed as 0.5 when it's
> supported by the IEEE754. Even if that wasn't question, it is my
> question now.
> 
> IEEE754 is capable of representing 0.5 with perfect precision; in fact,
> it would be `00111111000000000000000000000000'.
> 
> My question is why [0.1, 0.2 .. 1.0] comes up with an imprecise
> midpoint:
> [0.1,0.2,0.30000000000000004,0.4000000000000001,0.5000000000000001,0.6000000000000001,0.7000000000000001,0.8,0.9,1.0]
> 
> My initial guess is that the expansion is done by working out the
> difference between the first two elements and using that to generate the
> rest. This also makes me question why 0.1 is shown properly when it
> can't be represented precisely in IEEE754. Quickly rolling own list
> generation function:
> 
> *Main> let f x y = x : f y (y + y - x)
> *Main> take 10 $ f 0.1 0.2
> [0.1,0.2,0.30000000000000004,0.4000000000000001,0.5000000000000001,0.6000000000000001,0.7000000000000001,0.8,0.9,1.0]
> 
> reveals the same result as the short-hand which would imply that it's
> exactly what it's doing (for the simple case). My question for why can
> 0.1 be shown properly still stands in this case.
> 
> On 06/02/13 00:12, Darren Grant wrote:
>> I'm not sure how CReal implements its values, but IEEE754 also supports
>> decimal formats preferred for accuracy in many applications. Take a look:
>>
>>    http://en.wikipedia.org/wiki/IEEE_floating_point
>>
>>
>> Cheers,
>> d
>>
>>
>>
>>
>> On Tue, Feb 5, 2013 at 3:24 PM, Patrick Mylund Nielsen
>> <haskell at patrickmylund.com <mailto:haskell at patrickmylund.com>> wrote:
>>
>>     http://floating-point-gui.de/
>>     http://floating-point-gui.de/formats/fp/
>>
>>     http://en.wikipedia.org/wiki/Floating_point#Accuracy_problems
>>
>>
>>     On Wed, Feb 6, 2013 at 12:08 AM, KC <kc1956 at gmail.com
>>     <mailto:kc1956 at gmail.com>> wrote:
>>
>>         0.1 cannot be represented exactly in floating point.
>>
>>         0.5 can be represented exactly.  Why?
>>
>>
>>         On Tue, Feb 5, 2013 at 2:41 PM, yi lu
>>         <zhiwudazhanjiangshi at gmail.com
>>         <mailto:zhiwudazhanjiangshi at gmail.com>> wrote:
>>         > Hi,
>>         >
>>         > I found that in ghci, I input
>>         > [0.1,0.2..2]
>>         > and run, I get a result of
>>         >
>>         >
>>         [0.1,0.2,0.30000000000000004,0.4000000000000001,0.5000000000000001,0.6000000000000001,0.7000000000000001,0.8,0.9,1.0,1.1,1.2000000000000002,1.3000000000000003,1.4000000000000004,1.5000000000000004,1.6000000000000005,1.7000000000000006,1.8000000000000007,1.9000000000000008,2.000000000000001]
>>         >
>>         > But, as you know, it is not the exact answer.
>>         >
>>         > So, I wonder if there is something I can do to achieve a
>>         better performance
>>         > and get [0.1,0.2,0.3,0.4..] as the result.
>>         >
>>         > Thanks.
>>         >
>>         > _______________________________________________
>>         > Beginners mailing list
>>         > Beginners at haskell.org <mailto:Beginners at haskell.org>
>>         > http://www.haskell.org/mailman/listinfo/beginners
>>         >
>>
>>
>>
>>         --
>>         --
>>         Regards,
>>         KC
>>
>>         _______________________________________________
>>         Beginners mailing list
>>         Beginners at haskell.org <mailto:Beginners at haskell.org>
>>         http://www.haskell.org/mailman/listinfo/beginners
>>
>>
>>
>>     _______________________________________________
>>     Beginners mailing list
>>     Beginners at haskell.org <mailto:Beginners at haskell.org>
>>     http://www.haskell.org/mailman/listinfo/beginners
>>
>>
>>
>>
>> _______________________________________________
>> Beginners mailing list
>> Beginners at haskell.org
>> http://www.haskell.org/mailman/listinfo/beginners
>>
> 
> _______________________________________________
> Beginners mailing list
> Beginners at haskell.org
> http://www.haskell.org/mailman/listinfo/beginners
> 



More information about the Beginners mailing list