jik@athena.mit.edu (Jonathan I. Kamens) (06/07/90)
(Note the Followup-To to comp.unix.wizards -- which one to go to is pretty much a toss-up, so I chose the one I read. :-) In the BSD sources for the program compress (ucb/compress/compress.c), there exists the following function: prratio(stream, num, den) FILE *stream; long int num, den; { register int q; /* Doesn't need to be long */ if(num > 214748L) { /* 2147483647/10000 */ q = num / (den / 10000L); } else { q = 10000L * num / den; /* Long calculations, though */ } if (q < 0) { putc('-', stream); q = -q; } fprintf(stream, "%d.%02d%%", q / 100, q % 100); } This function accomplishes using only integer arithmetic what the following function accomplishes much more clearly, using floating point: prratio(stream, num, den) FILE *stream; long int num, den; { double ratio; ratio = (double) num / (double) den; fprintf(stream, "%0.2f%%", ratio * 100.0); } Not only is the former function much less clear than the latter, the former function screws up in some cases, while the latter one doesn't (on a VAXstation 3100, for example, plugging in 905762 and 908964 for num and den in both functions gives you 100.07% from the former function, and 99.65% from the latter (the latter is correct). Keen observers will notice that the constant in the first function is, of course, quite architecture-specific (or, at least, I think it is). Sigh. My question is, WHY were things done as shown in the first example? I can think of several reasons, but I'm not able to convince myself 100% that any of them were applicable when compress was written, and I'm even less able to convince myself that any of them are applicable now :-). Some of the reasons I've thought of: 1. Integer arithmetic is faster. Irrelevant when the function only gets called once or twice per compression, and that is the case here. 2. Some architectures don't have floating point arithmetic. Yeah, right. 3. The floating point arithmetic on some architectures is so inaccurate that the code above produces better results. Well, what do y'all think? WHY was the function originally written as shown in the first example above, and does it need to stay that way no, especially since it produces incorrect results? Jonathan Kamens USnail: MIT Project Athena 11 Ashford Terrace jik@Athena.MIT.EDU Allston, MA 02134 Office: 617-253-8495 Home: 617-782-0710