Path: utzoo!attcan!uunet!munnari.oz.au!goanna!ok From: ok@goanna.cs.rmit.oz.au (Richard A. O'Keefe) Newsgroups: comp.lang.c Subject: Re: Message-ID: <4035@goanna.cs.rmit.oz.au> Date: 22 Oct 90 02:56:57 GMT References: <1990Oct20.215718.15519@athena.mit.edu> Organization: Comp Sci, RMIT, Melbourne, Australia Lines: 39 In article <1990Oct20.215718.15519@athena.mit.edu>, phils@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.