Path: utzoo!utgpu!water!watmath!clyde!cbosgd!ihnp4!homxb!mhuxt!mhuxm!mhuxo!ulysses!allegra!alice!bs From: bs@alice.UUCP Newsgroups: comp.lang.c Subject: Re: Power operator? Summary: overloading inlining operators what C++ can and cannot do Message-ID: <7610@alice.UUCP> Date: 10 Jan 88 04:14:40 GMT References: <47000029@uxe.cso.uiuc.edu> <5260001@hplsla.HP.COM> Organization: AT&T Bell Laboratories, Murray Hill NJ Lines: 70 jima @ HP Lake Stevens, WA writes > Don't use ANSI-C, use C++, and overload the -> operator. > Then you can write: twoToTheTenth = 2.0->10.0; and there has been other references to C++ in this debate so I think it will be in place to explain what C++ can and cannot do vis a vis a power operator. (1) C++ does NOT enable you to change the meaning of operators applied to the built-in types. This implies that 2.0->10.0 is a plain C expression and therefore an error: you cannot use -> to dereference the floating point number 2.0 and even if you could -> requires a member name as its right hand operand so 10.0 would not do. Even if you had been able to make -> mean exponentiation, I would have cautioned against it: it is strongly recommended to use operator overloading ONLY where there is an established notation in some field of application to adopt. (2) C++ does NOT enable you to define new operators or in other ways change the syntax of C++. This implies that you cannot simply say: I'll make ** (or ^^ or *^ or) an operator (of some binding strength and associativity). So unless the ANSI C committe suddenly decides to reverse its stand on this issue and provides an exponentiation operator for C you cannot get it in C++. C++ does however offer two features that might help: function name overloading and inlining: overload pow; double pow(long, int); // simple integer algorithm double pow(double, int); // fairly simple algorithm double pow(double, double); complex pow(complex, double); // complex algorithm complex pow(complex,complex); // very complex algorithm There are other alternatives, but I hope the point is clear. The compiler has sufficient information to chose the right (i.e. simplest and/or fastest) pow() function on a per call basis. You don't need to pollute your name space with lipow(), dipow(), etc. pow(6,2); // call long pow(long,int); pow(6.0,2); // call long pow(double,int); pow(2,6.0); // call long pow(double,double); If you use inlining there is room for further refinement: inline double pow(long l, int i) { if (i==2) return l*l; else if ((i&~pow2_mask)==0) return _pow2_pow(l,i); else return _lipow(l,i); } now pow(x,2) will generate x*x pow(x,8) will generate _pow2_pow(l,8) pow(x,i) will generate _lipow(l,i) Note that the if-then-else business is handled at compile time and causes no spurious code to be emitted. The `code emitted' for the trivial example pow(6,2) above is simply the constant 36.