# to the nth power

Richard A. O'Keefe ok at goanna.cs.rmit.oz.au
Sun Nov 11 16:32:14 AEST 1990


In article <1990Nov10.224939.23622 at dirtydog.ima.isc.com>, karl at ima.isc.com (Karl Heuer) writes:
> In article <4233 at goanna.cs.rmit.oz.au> ok at 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 <math.h>
	
	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.



More information about the Comp.lang.c mailing list