Re: floor problems
- To: mathgroup at smc.vnet.net
- Subject: [mg8166] Re: [mg8113] floor problems
- From: David Withoff <withoff>
- Date: Sat, 16 Aug 1997 11:51:10 -0400
- Sender: owner-wri-mathgroup at wolfram.com
> Hello Mathematica users. > > I had a very frustrating time trying to debug some work I was doing in > Mathematica. I finally pared it down to a problem with the Floor > function, and I have illustrated my concern below. I am using M 3.0 and > a Mac computer. Does anyone have any advice or could you tell me if I > am doing something wrong? > > Floor[(.7 67 10)] > > 469 > > Floor[(67 10 .7)] > >468 > > Sincerely, > > Tom De Vries > -- > Vermilion Home Education Program > > email: tom.devries at schoolofhope.org >email: toad at planet.eon.net I think that there are two distinct questions here: 1) Why is Floor[(.7 67 10)] different than Floor[(67 10 .7)] 2) Since the exact result from 7/10 67 10 is 469, why does Floor[(67 10 .7)] return 468? The answer to the first question is that this is a consequence of the limitations of machine arithmetic. The same "bug" is present in nearly all computer software. As distressing as this may seem, the fact is that multiplication of machine numbers is not commutative. Here, for example, is a simple C program: -------------------------------------------------------------- #include <math.h> main() { double x, y; x = floor(0.7 * 67 * 10); y = floor(67 * 10 * 0.7); printf ("floor(0.7 * 67 * 10) = %f\n", x); printf ("floor(67 * 10 * 0.7) = %f\n", y); } --------------------------------------------------------------- which on my computer gives a result which is equivalent to the result from Mathematica. floor(0.7 * 67 * 10) = 469.000000 floor(67 * 10 * 0.7) = 468.000000 Lots of people have devoted decades of their lives to stabilizing numerical algorithms against the effects of this and other idiosyncracies of machine arithmetic. The answer to the second question, again both in Mathematica and in other systems, is that this is a design decision. An inexact number (a number in which the last digits are uncertain) is usually best thought of as an interval rather than as a point. For example, a number like 2.00000 can be thought of as the best available six-digit representation for any number between 1.9999995 and 2.000005. Since this interval includes 2, there is an obvious question about whether the "floor" of that number should be 2 or 1. There are lots of ways to handle this ambiguity which have different advantages in different situations, but eventually it comes down to a design decision. In Mathematica, one of the primary reasons for including variable-precision arithmetic is to provide a way to get around the idiosyncracies of machine arithmetic. Variable-precision is not without idiosyncracies either, but it is far more reliable and consistent than machine arithmetic. With variable precision arithmetic, rather than machine arithmetic, you should be able to get consistent results from these calculations. The best solution, however, for this and almost any other similar problem in numerical analysis, whether you write this program in C or in Fortran or in Mathematica or in any other system, is to arrange your calculation so that it is not sensitive to how the system chooses to handle these ambiguities. Dave Withoff Wolfram Research