<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