Path: gmdzi!unido!mcsun!uunet!tut.cis.ohio-state.edu!zaphod.mps.ohio-state.edu! usc!snorkelwacker!bloom-beacon!athena.mit.edu!jik From: j...@athena.mit.edu (Jonathan I. Kamens) Newsgroups: comp.unix.wizards,comp.lang.c Subject: function "prratio()" in sources to BSD compress Message-ID: <1990Jun7.023616.25034@athena.mit.edu> Date: 7 Jun 90 02:36:16 GMT Sender: n...@athena.mit.edu (News system) Reply-To: j...@athena.mit.edu (Jonathan I. Kamens) Followup-To: comp.unix.wizards Organization: Massachusetts Institute of Technology Lines: 70 Posted: Thu Jun 7 03:36:16 1990 (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 j...@Athena.MIT.EDU Allston, MA 02134 Office: 617-253-8495 Home: 617-782-0710
Path: gmdzi!unido!mcsun!uunet!snorkelwacker!apple!agate!riacs!jaw From: j...@riacs.edu (James A. Woods) Newsgroups: comp.unix.wizards Subject: Re: function "prratio()" in sources to BSD compress Message-ID: <1990Jun7.184525.962@riacs.edu> Date: 7 Jun 90 18:45:25 GMT References: <1990Jun7.023616.25034@athena.mit.edu> Organization: RIACS, NASA Ames Research Center Lines: 13 Posted: Thu Jun 7 19:45:25 1990 good eye. the original was floating point, like your suggestion, and i wrote it knowing the floats were not a cpu drain. it was changed by ken turkowski (still of apple?) to accomodate a pdp 11 without floating point hardware. i agree that it should revert to floating point. better yet would be to speedup dan bernstein's 'squeeze', a miller/wegman/ziv/lempel coder which has better c-rates. ames!jaw