<None>

Richard A. O'Keefe ok at goanna.cs.rmit.oz.au
Mon Oct 22 12:56:57 AEST 1990


In article <1990Oct20.215718.15519 at athena.mit.edu>, phils at athena.mit.edu (Philip R. Thompson) writes:
> Here's function that has annoying round-off errors.

Step 1.  If we have Degrees, Minutes, and Seconds as integers:

	double degrees(int Degrees, int Minutes, int Seconds)
	    {
		return ((Degrees*60.0 + Minutes)*60.0 + Seconds)/3600.0;
	    }

Things to note about this:  the floating-point constants here can be
represented *exactly*, as can the values of Degrees, Minutes, and Seconds;
the multiplications yield integral values (in floating-point format), so
are likely to be exact (and in IEEE arithmetic *must* be);
so the only place that error can creep in is the division (don't convert
that division to multiplication by the reciprocal).  In IEEE arithmetic,
then, this will be out by 1 ULP at most.

Step 2.
    The problem with the original code was that it read in the angle
      .
    DD MM' SS"
    in the form DD.MMSS (as a floating-point number) and then tried
    to extract DD, MM, and SS from that.  It's best to read them as
    integers.  If you want to read that format, do

	scanf("%d.%2d%2d", &Degrees, &Minutes, &Seconds);

    I would actually recommend a different input format, perhaps
	DD.MM'SS"
    read using
	scanf("%d.%d'%d\"")
    as 120.12'30" is rather more obviously degrees.minutes'seconds"
    than 120.1230, which looks more like 120.1230 degrees.  It's
    also easier to get the zeros right: 120.0'15" is unlikely to be
    a mistake, but 120.015 is a likely mistake in the other format.

-- 
Fear most of all to be in error.	-- Kierkegaard, quoting Socrates.



More information about the Comp.lang.c mailing list