2006-07-28

Controlling Floating Point Math Without Contexts

It's funny, a great deal of the problem with floating point is because different applications desire different behaviours, but there's no good way to control those behaviours. Usually there's only a single global context, but this breaks encapsulation in all sorts of nasty ways. Sometimes (such as in my previous post, Floating Point and NaNs in Python) there is a context object, but using methods from it becomes quite tedious.

I think there is better option out there, and it goes like this...

n = roundup(1 / 3)

The operation “1 / 3” would not do the math. Instead it would create an object that says what operation is to be performed and with what operands. This then gets passed to the roundup function which does the specified operation at its own precision.

Some more complicated examples:

e = roundup(m*rounddown(c**2))
rn = roundnearest
z = rn(rn(sum([
rn(list_old[b-1] % mod),
rn(list_old[b] % mod),
rn(list_new[b-1] % mod)
])) % mod)

As you can see this “delayed rounding” allows you to retain the use of normal math operators. There are, however, still some questions to be answered, mostly about what happens when you don't use the round functions immediately. Some possible answers are:
  • Raise an exception. Failing to use a round function immediately is always an error.
  • Apply a default rounding. This allows the current Python behaviour to be retained.
  • Compound operations with no intermediate loss. “roundup(m*c**2)” would only round once. Possibly very difficult and expensive to do.
  • Switch to intervals. “1 / 3” would produce an interval along the lines of “0.333..0.334”. Repeated operations would expand the “size” of the interval but it would remain correct in a mathematical sense. There are further questions of how to round an interval which does not have a minimal “size”. I plan to post about this later.
My personal favourite is intervals, as they are mathematically correct while still having good performance and a simple implementation. Unfortunately I have yet to explore how useful they would be for real programs.