gnu@hoptoad.uucp (John Gilmore) (01/10/88)
I guess most people who are talking about problems with pow() can't think like a (draft proposed) ANSI C compiler. Suppose you have a dumb math library. In <math.h> you put a declaration like: double pow(double, double); and write the library routine, and you are done. Now users can call this routine with integers, floats, doubles, whatever, and it works, because the function includes a prototype. E.g. zap = pow(x, 2); works, as does zap = pow(x, 2.0); oot = pow(x, 0.5); etc... Now suppose that you have a smart compiler and math library. In <math.h> you do: #define pow _compiler_pow where _compiler_pow is recognized as a keyword by the compiler. This is a two-argument function built into the compiler -- it *knows* the types of the operands, etc, just like any other built in primitive function, like addition or multiplication or sizeof. So if the user codes: zap = pow(x, 2); it can easily see to multiply x by itself. If you code zap = pow(x, 2.0); it can *also* see to multiply x by itself (if your float representation can't hold exact values of small integers, you are already in trouble). If you code: oot = pow(x, .5); then it can generate a square root instruction (ditto representation of .5). And if you code whoknows = pow(x, y) then it generates a subroutine call to the dumb library routine. Does *anybody* have a problem with this??? I think it would be crazy to change the standard for something like this. Adding new multi-character arithmetic operators to the language at the final stage of review? Be serious. We laughed at ( ), we roared at noalias, who would believe us if we overloaded ** to mean a crippled float/int-only exponentiation? we already have one crippled math op (% doesn't work on floats, for no reason), why add another? -- {pyramid,ptsfa,amdahl,sun,ihnp4}!hoptoad!gnu gnu@toad.com I forsee a day when there are two kinds of C compilers: standard ones and useful ones ... just like Pascal and Fortran. Are we making progress yet? -- ASC:GUTHERY%slb-test.csnet
gwyn@brl-smoke.ARPA (Doug Gwyn ) (01/11/88)
In article <3812@hoptoad.uucp> gnu@hoptoad.uucp (John Gilmore) writes: > double pow(double, double); >... Now users can call >this routine with integers, floats, doubles, whatever, and it works, No, it doesn't! First, it evaluates to a double, which is not what is wanted in many cases, but more importantly, it doesn't work at all for some well-defined sets of integer operands. However, the point about using a mapping onto a compiler intrinsic to obtain optimization is important; this can be done for many functions, including strcpy() etc. and many math-like functions, depending on what the run-time code (as opposed to library) environment will support.
blm@cxsea.UUCP (Brian Matthews) (01/12/88)
John Gilmore (gnu@hoptoad.uucp) writes: |[Good reasons why function prototypes and a smart compiler make the | pow function just fine...] |Does *anybody* have a problem with this??? I think it would be crazy |to change the standard for something like this. Adding new multi-character |arithmetic operators to the language at the final stage of review? |Be serious. We laughed at ( ), we roared at noalias, who would believe |us if we overloaded ** to mean a crippled float/int-only exponentiation? |we already have one crippled math op (% doesn't work on floats, for no reason), |why add another? I'm sure somebody has a problem with this, but not me. I would be in favor of adding a power operator iff: 1. It works with both integral and floating point types, just like all of the other arithmetic operators (yes, expect %), 2. It followed the same rules in regards to type promotion as the other arithmetic operators, and 3. A syntax is proposed which doesn't break existing code or require the compiler to choose between two different meanings to a statement based upon the types of the operands. This means ** and -> are both unacceptable. I would also say ^^ is unacceptable in the hopes of getting a boolean exclusive-or. 4. A corresponding op= operator was added (i.e. like +=, -=, etc.) In other words, make the exponentiation operator look like part of the language, instead of something hurriedly tacked on. This is especially true when there is already a good way of doing exponentiation, as outlined by John in the article I quoted. -- Brian L. Matthews "A power tool is not a toy. ...{mnetor,uw-beaver!ssc-vax}!cxsea!blm Unix is a power tool." +1 206 251 6811 Computer X Inc. - a division of Motorola New Enterprises
jk@hpfelg.HP.COM (John Kessenich) (01/12/88)
I agree that an exponentiation operator makes sense in 'C' for small integer exponents for the many good reasons given elsewhere, and support its addition (but not if it means more delay). Also, its precedence obviously belongs somewhere between that of (not inclusive) unary operators and punctuation operators. But, since exponentiation is not associative, order of evaluation is also important (what is (x ** 2 ** 3) ?). I propose the more mathematically correct interpretation of right to left (as in assignment), not the normal left to right (used for most operators). That is, 3 2 8 6 x ** 2 ** 3 means x which equals x not x thus x ** 2 ** 3 is interpreted as x ** (2 ** 3). By the way, if *^ is adopted for exponents, why not /^ for roots? (don't take this too seriously :-) ). --------------- John Kessenich
ericb@athertn.Atherton.COM (Eric Black) (01/12/88)
In article <3812@hoptoad.uucp> gnu@hoptoad.uucp (John Gilmore) writes: >I guess most people who are talking about problems with pow() >can't think like a (draft proposed) ANSI C compiler. > >Suppose you have a dumb math library. In <math.h> you put a declaration like: > > double pow(double, double); >[...] >Now suppose that you have a smart compiler and math library. In ><math.h> you do: > > #define pow _compiler_pow > >where _compiler_pow is recognized as a keyword by the compiler. >[...] >Does *anybody* have a problem with this??? Seems to work as far as it goes... Your solution still requires the arguments to first be promoted to double, and the return result converted from double to whatever. I have done graphics and number crunching where that conversion both ways is not desired (float precision is adequate) and it takes an unacceptable performance hit. In fact, on some systems (e.g. PR1ME/PRIMOS) a common practice is to use a kludgey compiler "private keyword" to tell the compiler it's making an inter-language call (in PRIMOS C it's the modifier "fortran", of all things!) to avoid this promotion to double, and write the called routine in FORTRAN *just so it doesn't expect its incoming arguments to be double*, even though they are declared as float (because C requires them to be promoted to double on the way in, you see...). Now, in the first instance above, it is clear that the arguments MUST be converted to double. In the second (the builtin), I suppose the compiler could somehow be told (a #pragma?) not to do that, but that's really wierd and unexpected behavior. I suppose that means I really don't have a problem with your proposed solution, John, because this is a built-in (!) problem with C as it is, and your solution really doesn't address my problem any less than C does now. Is there a provision I haven't seen that solves my problem? If so, then "Never mind!". If not, I'd much prefer that it be added than any built-in power operator. -- Eric Black "Garbage in, Gospel out" UUCP: {sun!sunncal,hpda}!athertn!ericb Domainist: ericb@Atherton.COM
decot@hpisod2.HP.COM (Dave Decot) (01/19/88)
Nobody has addressed the idea of using %% as the power operator. It would not conflict with any other possible extension that anyone has mentioned, and is not riskier syntax than any other. Dave Decot hpda!decot
jk@hpfelg.HP.COM (John Kessenich) (02/02/88)
I have thought about using macros for squaring expressions, and problem is that they *do* require a temp. This makes it impossible to do the following: #define SQR(exp) ???? x = y + z * SQR(a+b); Either a temp must be available so one can write #define SQR(exp) (t=(exp), t*t) Or one must write #define SQR(x,exp) {int t; t=(exp); x = t*t;} which cannot be used in expressions. Conclusion? there is not a good substitute for a real power operator. (This does not mean there should be a power operator. :-) --------------- John Kessenich