Path: utzoo!utgpu!water!watmath!clyde!rutgers!gatech!purdue!i.cc.purdue.edu!j.cc.purdue.edu!k.cc.purdue.edu!l.cc.purdue.edu!cik From: cik@l.cc.purdue.edu (Herman Rubin) Newsgroups: comp.lang.c Subject: Re: Power operator? Summary: We need flexibility, not rigidity Message-ID: <651@l.cc.purdue.edu> Date: 10 Jan 88 12:13:48 GMT References: <47000029@uxe.cso.uiuc.edu> <10063@mimsy.UUCP> <646@l.cc.purdue.edu> <3312@ihlpf.ATT.COM> Organization: Purdue University Statistics Department Lines: 74 In article <3312@ihlpf.ATT.COM>, nevin1@ihlpf.ATT.COM (00704A-Liber) writes: > In article <646@l.cc.purdue.edu> cik@l.cc.purdue.edu (Herman Rubin) writes: > .In article <10063@mimsy.UUCP>, chris@mimsy.UUCP (Chris Torek) writes: > .. In article <47000029@uxe.cso.uiuc.edu> mcdonald@uxe.cso.uiuc.edu writes: > .Similar thinking would require one to write x = sub(y, z) instead of > .x = y - z. This is a major design flaw in all HLLs which I know. > > In other words, are you saying that all functions of two variables which do not > modify the variables should always be declared with infix notation?? I have a > hard enough time remembering all the infix operators now (there are at least > 19) and their order of precedence and associativity. :-) How would you define > the order of precedence and associativity for these functions? There is a vast difference between requiring infix notation and permitting infix notation. As far as precedence is concerned, who remembers the order for most combinations? I would just as soon require parentheses for this problem. What is the relative precedence of << (shift) and +? The various people I asked came up with the _same_ answer. The C compiler on the Pyramid came up with the other. > .Another is that there are _several_ power functions; the one in the standard > .math library is the slowest one, which must be used if the exponent is non- > .integral. Standard FORTRAN treats y ** z to be of the type of y if z is > .typed integer, and most implementations use the binary representation of z to > .compute the result in that case, and even to have several of the most important > .cases "precoded", i.e, y ** 2 is usually done as y * y; even if this is not > .done, in Torek's example, if it is known that the 7 is an integer the resulting > .code will run at least an order of magnitude faster than the pow function. > > Write a function (call it mypow()) to call the correct pow() function depending > on its arguments; why should this be built in to the language if you can easily > define it with the operators given? That was fine for Fortran, a language > designed to handle large amounts of number crunching. C is more > general-purpose than that. (BTW, I really don't understand your 'use the > binary implementation of z ...' remark.) That C is more general than a number-crunching language is no reason for C to do a bad job of number-crunching. We do not need any tradeoffs here. Your argument about introducing a new function mypow() completely misunderstands the problem. How would mypow() possibly know that the second argument is of type integer, and that in that case it should proceed according to the type of the first argument? Now you may say that I should also feed it the types of the arguments. This is contrary to the whole idea of overloaded operators. If we did not have this, instead of the 19 binary operations you mentioned above, we would have more than 50 and have to remember all their names and precedences. The most common case of power is that in which the exponent is an integer, frequently a small integer. If the integer is a small fixed integer (this is decided by the compiler), the operation should be unrolled by the compiler into a sequence of multiplications, including squarings, with an inversion if the exponent is negative. The other important special case is that in which the exponent is either a large integer or a variable integer. In that case the operation should either be a loop using a sequence of multiplications, some of which are squaring operations, based on the binary representation of the exponent, with an inversion if the exponent is negative. Whether this should be inline or a function call is machine dependent; I suspect that on most machines it should be inline. Only if the exponent is not of an integer type should a function like pow() be called. Possibly this function should check whether in fact the exponent is an integer; the various costs would have to be analyzed to decide whether this is worthwhile. But this is the most that could be with your suggestion of a function mypow(). It is unusual that one is interested whether a real exponent happens to be an integer, but it is not unusual to have an exponent something that is known to be an integer. -- Herman Rubin, Dept. of Statistics, Purdue Univ., West Lafayette IN47907 Phone: (317)494-6054 hrubin@l.cc.purdue.edu (ARPA or UUCP) or hrubin@purccvm.bitnet