More accurate summations [was Re: This math scares me]
Edward Jason Riedy
ejr at cs.berkeley.edu
Fri Mar 16 22:43:57 EST 2001
More information about the Python-list mailing list
Fri Mar 16 22:43:57 EST 2001
- Previous message (by thread): More accurate summations [was Re: This math scares me]
- Next message (by thread): More accurate summations [was Re: This math scares me]
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
And <jurgen.defurne at philips.com> writes: - - Try summing all financial operations of one day together, or - better, all operations involving percentages and then adding them - together : cumulative errors. More concretely, look at the Vancouver Stock Exchange index's problems of the late 70s-early 80s. They had chosen to truncate floating point values rather than round them, causing a downward drift of around 20 points a month[1]. You could say that's because of poor handling of floating-point arithmetic, and you'd be right. However, just about every inaccuracy in floating-point financial calculations can be attributed to poor handling of fp arithmetic. That doesn't mean floating point is a poor choice for all financial programs. Indeed, the HP financial calculators _all_ use floating point, although decimal. Those calculators were designed twenty-odd years ago, and they're still selling for almost as much as a Pilot. If you want a _very_ accurate sum for all the operations in one day, use the following algorithm. It is often attributed to Kahan, but, if I recall his comments correctly, he's not entirely sure of the origins of the embodied idea. Other names around this style of algorithm are Moller (with a backwards slash through the o), Dekker, Pichat, Knuth, Bohlender, and Linnainmaa in no particular order. That's a surprising number of people for just adding numbers. ;) class DistilledSum: "Keep an accurate running sum." def __init__ (self): self.s = 0.0 self.c = 0.0 def add (self, x): "Incorporate x into the running sum." y = x - self.c t = self.s + y self.c = (t - self.s) - y self.s = t def value (self): "Return the sum itself." return self.s def asTuple (self): "Return both the sum and the error term." return (self.s, self.c) The accumulated error in s from floating-point calculations is at most one unit in the last place of each summand x, and the value of c gives you a tighter bound on that error. With not entirely horrible amounts of extra work, you can have however much precision you need[2]. Unless your numbers are horribly scaled (perhaps the debt and GNPs of the entire globe along with a person's), this in double plus rounding the stored answer to float works wonders for financial accumulations. You can find an explanation of how this works either in [2] or [3]. Essentially, the self.c term serves as a small correction. The trick with (t - self.s) - y first zeros the high-order bits that are shared between the old and new sum, then zeros the bits shared with the pre-corrected x, giving a new correction. Jason, unsure of how to create other languages' characters from this particular keyboard... [1] Q20 at http://catless.ncl.ac.uk/Risks/3.41.html#subj4.1 [2] http://citeseer.nj.nec.com/priest92propertie.html [3] http://www.validlab.com/goldberg/paper.ps --
- Previous message (by thread): More accurate summations [was Re: This math scares me]
- Next message (by thread): More accurate summations [was Re: This math scares me]
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
More information about the Python-list mailing list