MathGroup Archive 1997

[Date Index] [Thread Index] [Author Index]

Search the Archive

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


  • Prev by Date: Re: floor problems
  • Next by Date: Re: UnsameQ implementation
  • Previous by thread: Re: floor problems
  • Next by thread: Re: floor problems