Path: utzoo!utgpu!news-server.csri.toronto.edu!rutgers!cs.utexas.edu!uunet!munnari.oz.au!goanna!ok From: ok@goanna.cs.rmit.oz.au (Richard A. O'Keefe) Newsgroups: comp.lang.c Subject: Re: # to the nth power Message-ID: <4239@goanna.cs.rmit.oz.au> Date: 11 Nov 90 05:32:14 GMT References: <90305.005050CJH101@psuvm.psu.edu> <1990Nov10.224939.23622@dirtydog.ima.isc.com> Organization: Comp Sci, RMIT, Melbourne, Australia Lines: 59 In article <1990Nov10.224939.23622@dirtydog.ima.isc.com>, karl@ima.isc.com (Karl Heuer) writes: > In article <4233@goanna.cs.rmit.oz.au> ok@goanna.cs.rmit.oz.au (Richard A. O'Keefe) writes: > >SVID release 2, vol 1, p 170: [Specs for pow().] If the answer was > >significantly in error (compared with the code in Cody & Waite, say) it would > >have been appropriate to complain to the vendor. > How much is "significantly"? I said "significantly" in order to avoid giving any definite answer to that question! It all depends. (There, I managed to use the phrase that proves I'm an expert...) > An error of a single ulp is enough to cause > (int)pow(2.0, 3.0) to return 7 instead of 8 (which it does, on several current > implementations). Well, yes, but so what? That's an incredibly stupid way to calculate integer powers in the first place. What you want is ROUND TO NEAREST, not TRUNCATE TOWARDS ZERO. If you have the IEEE "appendix function" drem(), int iround(double x) { return x - drem(x, 1.0); } ... eight = iround(pow(2.0, 3.0)); > So unless the standards bodies (*not* the individual > vendors) are willing to guarantee exactness for this function, using pow() is > an unportable solution to the problem of integer-to-integer exponentiation. Using pow() is just fine if you ROUND instead of TRUNCATING. (Oh for the good old Algol 60 days...) As a matter of genuine curiosity, just how useful is a general integer power function anyway? On a 32-bit machine, you can compute 2**n for 0 <= n <= 30 only (might as well use a table), and for larger numbers the useful range of n is smaller. (For 10**n, the range is 0 <= n <= 9. Again, you would be better off with a table.) I fully appreciate that integer powers are useful in languages like Lisp without artificial restrictions on integer size, but in __C__? Does anyone know why C hasn't got a round() function and why ANSI failed to add one? Using ANSI functions, we can do #include double round(double x) { double f = floor(x); double c = ceil(x); return x-f > c-x ? c : f; } #define iround(x) (int)round(x) Even if the "round to even when there is a tie" rule were insisted on (as I think it should) it's easy to implement. (I've posted one before.) -- The problem about real life is that moving one's knight to QB3 may always be replied to with a lob across the net. --Alasdair Macintyre.