accuracy problem in calculation

Dave Angel d at davea.name
Thu Nov 8 12:37:52 EST 2012


On 11/08/2012 12:05 PM, Debashish Saha wrote:
> (1500000000+1.00067968)-(1500000000+1.00067961)
> Out[102]: 2.384185791015625e-07
>
> 1.00067968-(1.00067961)
> Out[103]: 7.000000001866624e-08
>
> above i am showing the two different results,though the two outputs
> should be same if we do it in copy(the lass one is acceptable value).
> so my question is how to increase the accuracy(windows7(32bit)
> ,python2.7.2)

To improve accuracy, do some algebra before coding brute force.  If you
know you'll be subtracting two values that are nearly equal, see if you
can factor out the large part, and only subtract the small parts.

If you have a processor with 16 digits of float accuracy, and you
calculate an 18 digit sum, you're going to lose 3 digts at a minimum. 
Each sum has the same problem.  So now you have lopped off all the
digits that are different.  So subtracting them is meaningless.

Picture needing to know how thick a leaf is.  So measure the distance
from one side of it to the sun.  Then measure the distance from the
other side to the sun.  Now just subtract the answers.  Silly, isn't it?

You have  (a+b) - (a+c), where a is much larger than either b or c.  So
simplify it to b-c before programming it.  Oh, yeah, that's your second
approach.

More generally, if you have a sum of 3 or more values (which you can get
by just stating the problem as a + b + -a + -c), you can usually
minimize error by reordering the arithmetic, based on the sizes of the
items.  Fortunately Python has a library function that knows how to do that:

http://docs.python.org/2/library/math.html#math.fsum

If you want to postpone the problem so instead of hitting at 15 digits
or so, it hits at a few hundred digits, you could use decimal.Decimal,
which is a standard library in Python.  It permits you to specify your
own precision, instead of being what Intel (professor Kahn) decided on
in about 1985.  They constrained themselves to what could be encoded in
8 bytes.  Naturally, if you ask for much higher precision with Decimal,
you'll pay for it with space and/or time.  But apparently in 3.3, they
did a very good job minimizing the time it takes, for reasonable precision.

Interestingly, I got a similar question in about 1977, concerning a trig
package I had microcoded.  A man was measuring the flatness of a
hypothetical level table (which must be curved, of course).  And he did
it with trig, and effectively by subtracting two measurements to the
center of the earth.  I was able to simplify his problem using some
geometry (similar triangles) to get all the accuracy he needed.  And
strangely enough, the trig canceled out and was unnecessary.


-- 

DaveA




More information about the Python-list mailing list