mcdonald@uxe.cso.uiuc.edu (01/06/88)
I've been wondering why there is no power operator in C. Did the ANSI committee consider adding one, and if so, why wasn't it done? I'm referring to the construct in fortran X**2 or X**7 . This would seem to be extremely useful and trivial to implement. Doug McDonald
chris@mimsy.UUCP (Chris Torek) (01/07/88)
In article <47000029@uxe.cso.uiuc.edu> mcdonald@uxe.cso.uiuc.edu writes: >I've been wondering why there is no power operator in C. There is: #include <math.h> ... double a, x; ... a = pow(x, 7.); Unless you write `#undef pow' after `#include <math.h>', you may get in line code (fpushf (fp-4); fftod; fpushd $0d7.0; fexpd etc). -- In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7690) Domain: chris@mimsy.umd.edu Path: uunet!mimsy!chris
ix426@sdcc6.ucsd.EDU (tom stockfish) (01/07/88)
In article <47000029@uxe.cso.uiuc.edu> mcdonald@uxe.cso.uiuc.edu writes: >I've been wondering why there is no power operator in C. Did the ANSI >committee consider adding one, and if so, why wasn't it done? I'm >referring to the construct in fortran X**2 or X**7 . This would seem >to be extremely useful and trivial to implement. > >Doug McDonald Useful, yes, but fortran syntax (x**y) already means "fetch the value at address y and multiply by x". For example, double x = 2; double y = 3; double *z = &y; printf( "%f\n", x**z ); prints "6". My only complaint about C's operator symbols is that "*" is grossly overworked. For example, the following code might look o.k., but do you see what's wrong? In fact, it even compiled (!) with no error messages or warnings on the Berkeley Unix's cc a few years back (no, it didn't run properly). f( x, y ) double *x, *y; { return *x/*y; } Of course, Everyone Knows that polynomials should never be calculated as, e.g. a*x**4 + b*x**3 + c*x**2 + d*x + e (using fortran notation), so that an exponential operator shouldn't be used here, but there are other important uses such as (again using fortran) f(x) ** 2 where I don't want to call f() twice, and I don't want to clutter up my code with temporaries. The syntax x^y is bad because this is already defined for integers as bit-wise exclusive or. x^^y is a possibility, altho those who want ^^ for logical exclusive or will I'm sure complain. x%%y would probably be o.k., but it looks pretty wierd. I suppose x!y would work, but I would guess that the numerical people who want exponentiation as an operator would confuse ! with factorial. How about x@y ? How about x..y ? How about some better suggestions? -- || Tom Stockfisch, UCSD Chemistry tps@chem.ucsd.edu
gwyn@brl-smoke.ARPA (Doug Gwyn ) (01/07/88)
In article <47000029@uxe.cso.uiuc.edu> mcdonald@uxe.cso.uiuc.edu writes: >I've been wondering why there is no power operator in C. Did the ANSI >committee consider adding one, and if so, why wasn't it done? Yes, X3J11 considered this and numerous other obvious suggestions for additions to the language. It reaffirmed the original deliberate C design decision to not build in an exponentiation operator, but rather leave it to a library function (pow()). The idea is that an exponentiation operator hides a potentially large amount of computation, which runs counter to "the spirit of C". It is true that (for example) expression ** 2 would be convenient, for much the same reasons as C's op= operators. However, this did not overcome the reasons for the original design. REMINDER: This is my personal opinion. If you feel strongly about this, comment to X3J11 during the second formal public review. Be sure to provide overwhelming reasons for making the change.
cik@l.cc.purdue.edu (Herman Rubin) (01/07/88)
In article <10063@mimsy.UUCP>, chris@mimsy.UUCP (Chris Torek) writes: > In article <47000029@uxe.cso.uiuc.edu> mcdonald@uxe.cso.uiuc.edu writes: > >I've been wondering why there is no power operator in C. > > There is: > > #include <math.h> > ... > double a, x; > ... > a = pow(x, 7.); > > Unless you write `#undef pow' after `#include <math.h>', you may > get in line code (fpushf (fp-4); fftod; fpushd $0d7.0; fexpd etc). I think everyone should consider this unsatisfactory. One reason is that requiring the writing of a subroutine call is that this requires people to use that notation instead of writing x = y ** z or x = y ! z. 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. 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. -- 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
V4039%TEMPLEVM.BITNET@CUNYVM.CUNY.EDU (Stan Horwitz) (01/08/88)
Chris Torek says the function pow(x,y) in C's math library is C's power operator. Sorry Chris, the pow(x,y) is not an operator, it is a FUNCTION. Syntactically, there is a difference, though the result is the same. The question still stands. Why does C have no symbol to serve as a power operator. There are so many symbols to use, and it would be easy to implement. Stan Horwitz V4039 at TEMPLEVM
pardo@uw-june.UUCP (David Keppel) (01/08/88)
[Why isn't there a power (e.g., a**2) operator in C?] The original intent of C was simplicity. Having ** is a fine idea, but we have to draw a line somewhere and it was defaulted for us by K&R a long time ago. If we have ** then perhaps we should also have ||= ? Worried about runtime overhead of calling pow(3m)? Talk to somebody about inline code expansion or use C++. ;-D on (Does anybody have a C->Cobol Compiler ?-) Pardo
chris@mimsy.UUCP (Chris Torek) (01/08/88)
>In article <10063@mimsy.UUCP> I wrote: >> a = pow(x, 7.); >>Unless you write `#undef pow' after `#include <math.h>', you may >>get in line code (fpushf (fp-4); fftod; fpushd $0d7.0; fexpd etc). In article <646@l.cc.purdue.edu> cik@l.cc.purdue.edu (Herman Rubin) writes: >I think everyone should consider this unsatisfactory. > >One reason is that requiring the writing of a subroutine call is that >this requires people to use that notation . . . . This is indeed an annoyance, as there is no way to define a shorthand version. Writing `x = plus(y, z)' instead of `x = y + z' is less familiar. On the other hand, I know of no language that lets me write 4 3 x a = ------------------ 2 (b - c/7) (k - x) as a statement. I do not believe this is a serious problem, just as I do not believe that `:=' is particularly better or worse than `=' for assignment. It is just different. (Well, `:=' requires shift-unshift, and the two keys are under the same finger for touch typists, which is bad.) >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. (One solution to the dichotomy between builtin operators and other functions is to eliminate all the builtin operators. I happen to LIKE this idea.) >Another is that there are _several_ power functions; the one in >the standard math library is the slowest one.... [at worst] 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. What pow function? Who said we were calling the pow function? :-) *You* see `pow'; the compiler sees `_builtin_pow', as defined in <math.h>. _builtin_pow can be arbitrarily fancy, including testing its second argument to see whether it is an integral value. You might get this inline code instead: fpushf (fp-4) # x fdupf fsquaref # pow(x,2) fdupf fsquaref # pow(x,4) faddf # pow(x,6) faddf # pow(x,7) -- In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7690) Domain: chris@mimsy.umd.edu Path: uunet!mimsy!chris
chris@mimsy.UUCP (Chris Torek) (01/08/88)
In article <11169@brl-adm.ARPA> V4039%TEMPLEVM.BITNET@CUNYVM.CUNY.EDU (Stan Horwitz) writes: > Chris Torek says the function pow(x,y) in C's math library is C's power >operator. Sorry Chris, the pow(x,y) is not an operator, it is a FUNCTION. Is not! See the dpANS. If you want a function, you must `#undef pow'. >Syntactically, there is a difference. . . . True. I think this should be ignored. -- In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7690) Domain: chris@mimsy.umd.edu Path: uunet!mimsy!chris
gwyn@brl-smoke.ARPA (Doug Gwyn ) (01/08/88)
If someone wants to propose a good syntax for a built-in exponentiation operator, send it in during the second public review of the draft standard. I wouldn't mind having one, although the only way it is likely to occur at this point is if some other problem forces a third public review anyway (i.e., it won't be caused by adding the exponentiation operator). The x ** y syntax conflicts with existing C, which already ascribes a different meaning to this, although I do think that anyone who has been writing ** without a space in between deserves problems anyway. x ^ y is also already taken.
lupin3@UCSCB.UCSC.EDU (-=/ Larry Hastings /=-) (01/08/88)
+-In article <6982@brl-smoke.ARPA>, gwyn@brl.arpa (Doug Gwyn (VLD/VMB) <gwyn>) wrote:- +---------- | | If someone wants to propose a good syntax for a built-in exponentiation | operator, | .... | The x ** y syntax conflicts with existing C, which already ascribes | a different meaning to this, although I do think that anyone who has | been writing ** without a space in between deserves problems anyway. | | x ^ y is also already taken. | +---------- And me, in my half-delirious state.. suggest x *^ y ..... Think about it; "multiply to the power of" or something. Sure, it looks kind of dorky, but a) it's not used and b) there really ought to be SOMETHING. Or how about x tothepowerof y ..... :-) -- .. . . . . . . . . . . . .. . . . . . . . . . . . | _ _ _ _ |_| _ _ |_ -__ _ _ ARPA: lupin3@ucscb.ucsc.EDU L_ (_\( ( (_/ | |(_\_\ (_ || )(_)_\ UUCP: ...!ucbvax!ucscc!ucscb!lupin3 larry / hastings _/ BITNET: lupin3@ucscb@ucscc.BITNET ^v^v^vBoy, I'm glad I don't live in an alternate universe!^v^v^v Disclaimer: All original text above was pointless & random, & it makes me proud. . . . . . . . . . . . .. . . . . . . . . . . . ..
kers@otter.HP.COM (Christopher Dollin) (01/08/88)
Someone writes: >Similar thinking would require one to write x = sub(y, z) instead of >!
kers@otter.HP.COM (Christopher Dollin) (01/08/88)
GRR! Sorry for the previous two responses; I messed up using vi (spit) then pressed "w" instead of "W" in notes .... Chris Torke quotes Herman Rubin as saying ... [lots of preamble] >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. [lots of postamble] Pop11 allows any word to be declared as an operator with a particular precedence. Such a word must be a variable (or constant) having a procedure as its value; the effect of writing the wortd as an operartor is just to call its procedure value. All the built-in operators work this way (of course the compiler can optimise some of them to in-line code). A word can be a C-like name or one composed out of signs. So the user can declare operators like "--" or "<=>", or "cat", "pow", "without", etc. Regards, Kers | Why Lisp if you can talk Poperly?
V4039%TEMPLEVM.BITNET@CUNYVM.CUNY.EDU (Stan Horwitz) (01/09/88)
One more comment about the power operator. So far most of the arguments against it's use are reasonable, but not acceptable. If C can have an operator for such as % for modulo divide, why not one for exponentiation? Surely the same arguments against such a request can also be made against the inclusion of %. Anyway, sorry to drag down the group with this topic.
nather@ut-sally.UUCP (Ed Nather) (01/09/88)
In article <11169@brl-adm.ARPA>, V4039%TEMPLEVM.BITNET@CUNYVM.CUNY.EDU (Stan Horwitz) writes: > > Chris Torek says the function pow(x,y) in C's math library is C's power > operator. Sorry Chris, the pow(x,y) is not an operator, it is a FUNCTION. > Syntactically, there is a difference, though the result is the same. As a matter of interest, would there be any ambiguity in using a ^^ b instead of pow(a,b) ? I can see how the Fortran notation a**b is ambiguous if "b" could be a pointer ... -- Ed Nather Astronomy Dept, U of Texas @ Austin {allegra,ihnp4}!{noao,ut-sally}!utastro!nather nather@astro.AS.UTEXAS.EDU
fujiirm@yendor.UUCP (Roger Fujii) (01/09/88)
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: > > > > #include <math.h> > > ... > > double a, x; > > ... > > a = pow(x, 7.); > > I think everyone should consider this unsatisfactory. I suppose that strcpy, strcmp... are also unsatisfactory also. > One reason is that requiring the writing of a subroutine call is that > this requires people to use that notation instead of writing > > x = y ** z or x = y ! z. > > 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. Depends on what point of view. From a mathematical point of view, sure. But then, from a mathematical point of view, variable assignment (x = 1) makes no sense either (unless x never changes), even though its meaning is obvious in most programming languages. I think a *lot* of people are forgetting/misunderstanding exactly what 'c' is. C is basically an "abstract assember". All the actual language knows about are data types (ints, floats, doubles, structs...), certain *ELEMENTARY* operators (+, -, *, /, data copy, data compare..... - things that have a fair probability of having an assember equivalent), and control statements (ifs, gotos, subroutine calls...). [ I know this is a *gross* simplification, but this is what I think a fair assement of the language is ]. *EVERYTHING* else is done via function call. Therefore, having pow() makes much more *sense* than having a ** (this is not to say that it makes more intuitive sense, but rather that knowing the language, you would not expect the compiler to do this). I really don't think "well, FORTRAN has it" is really a valid reason for mucking up the language. This is not to say I do not want the language changed, but rather that I would like to see it changed within its "scope" or flavor, rather than because people want to make it look like another language. -- Roger Fujii - ACT, Reston, VA Phone: (703)471-9433 Internet: fujiirm@cml.rpi.edu UUCP: ..!{mimsy,sundc}!{prometheus,hqda-ai}!yendor!fujiirm
noise@eneevax.UUCP (Johnson Noise) (01/09/88)
In article <3933@uw-june.UUCP> pardo@uw-june.UUCP (David Keppel) writes: >[Why isn't there a power (e.g., a**2) operator in C?] > >The original intent of C was simplicity. Having ** is a fine idea, >but we have to draw a line somewhere and it was defaulted for us by K&R >a long time ago. If we have ** then perhaps we should also have ||= ? > I can concur with that. But, if you really MUST have a power operator, why not define one using the preprocessor? (I'm sure someone must have already suggested this, but so what). The subject of a power operator is a bit sundry, I think. I'm not sure, (correct me if I'm wrong), but I think there are even languages that do not have bit operators like &, |, !, ^, >>, << etc. I remember back in the days of FORTRAN when I actually had to write assembly routines to perform bit operations on integers. Lots of silly overhead just for one instruction. Anyway, C was designed to be used mostly for systems implementation, not necessarily for number crunching.
jima@hplsla.HP.COM ( Jim Adcock) (01/09/88)
Don't use ANSI-C, use C++, and overload the -> operator. Then you can write: twoToTheTenth = 2.0->10.0;
karl@haddock.ISC.COM (Karl Heuer) (01/09/88)
In article <10088@mimsy.UUCP> chris@mimsy.UUCP (Chris Torek) writes: >What pow function? Who said we were calling the pow function? :-) [Implying that "pow" might be implemented as a builtin] I have several problems with using pow() for integer powers. Unue, I dislike having to use floating point in otherwise "pure" integer code. ("difftime()", yuck.) Due, I suspect that most vendors will not optimize the statement "j = (int)pow((double)ifunc(), 2.0)" into what I want. Trie, it's possible that the cast to double throws away the lower bits of my left argument, which would yield an incorrect result. Kvare, it's just too verbose (and I won't remove the casts; some compilers would emit warnings without them). The proposals I've seen so far include: x ** y Already means "multiply by what y points to". x ^ y Already means "exclusive or". x ^^ y Some people want this reserved for logical (not bitwise) xor. x ! y Doesn't extend to an assignment form, since "!=" is taken. x *^ y Not bad; I could live with it. However, ANSI is unlikely to introduce new operator syntax anyway. pow(x,y) See above paragraph. I counterpropose "int ipow(int, int);", "long lpow(long, int);", and "double fpow(double, int);". These are easy to implement as either functions or builtins, and vendors will probably be more willing to inline-expand these functions than the full pow() function. Karl W. Z. Heuer (ima!haddock!karl or karl@haddock.isc.com), The Walking Lint
nevin1@ihlpf.ATT.COM (00704A-Liber) (01/09/88)
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: ...I've been wondering why there is no power operator in C. .. .. There is: .. a = pow(x, 7.); .I think everyone should consider this unsatisfactory. . .One reason is that requiring the writing of a subroutine call is that .this requires people to use that notation instead of writing . . x = y ** z or x = y ! z. . .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? . .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.) -- _ __ NEVIN J. LIBER ..!ihnp4!ihlpf!nevin1 (312) 510-6194 ' ) ) "The secret compartment of my ring I fill / / _ , __o ____ with an Underdog super-energy pill." / (_</_\/ <__/ / <_ These are solely MY opinions, not AT&T's, blah blah blah
ok@quintus.UUCP (Richard A. O'Keefe) (01/09/88)
There are two power operators: <any> ** double -> double /* pow() */ and <any> ** int -> double /* rtp() -- MISSING */ A quick check though a couple of books of statistical algorithms in Fortran showed me that <expr> ** k for k an integer known at compile time appeared roughly once each in fewer than 10% of the functions. The equivalent of pow() was even rarer. Having to write rtp(X, 3) instead of X**3 doesn't seem like such a big deal to me. It's not that common. What irks me is having to write my own rtp(). I know how to do it, but it's not as fast as the vendor could provide, and the vendor-provided one might even do IEEE-854-sensible things. Just to make it clear that pow() is not what is wanted: rtp(-2.0, 3) is -8.0 pow(-2.0, 3.0) involves taking the logarithm of -2.0 ...
gwyn@brl-smoke.ARPA (Doug Gwyn ) (01/09/88)
In article <10026@ut-sally.UUCP> nather@ut-sally.UUCP (Ed Nather) writes: > a ^^ b I think this is about as good a notation as we can get that is compatible with existing code. If several of you will please send in this suggestion, along with strong arguments, as formal public comments (when it's time, not just yet), I'll be happy to push for getting it adopted. I think the only way a substantive change like this could stand any chance of adoption at this point would be for some other substantive change to have already been accepted, so that this item would not be the sole cause for another delay in publishing the final standard. The strongest case I can think of that would justify a built-in exponentiation operator is messy_expression ** 2 (Note that is an integral power that can be highly optimized over the use of pow() to do the same job.)
farren@gethen.UUCP (Michael J. Farren) (01/09/88)
Seems to me that providing a power operator would violate, somewhat, one of the most important aspects of C - the relatively simple mapping between C operators and few, or even one, machine instruction. I can't think of any of the basic operators which don't map into a very small number of machine instructions; even floating point numbers do if you have some sort of floating point accelerator, even the most primitive. Exponentiation, generally, does not map so easily. Nor, for that matter, do any of the trig functions, and I don't hear a lot of complaints about the lack of a sine operator (whose symbol would be ~, of course :-) -- Michael J. Farren | "INVESTIGATE your point of view, don't just {ucbvax, uunet, hoptoad}! | dogmatize it! Reflect on it and re-evaluate unisoft!gethen!farren | it. You may want to change your mind someday." gethen!farren@lll-winken.llnl.gov ----- Tom Reingold, from alt.flame
gwyn@brl-smoke.ARPA (Doug Gwyn ) (01/09/88)
In article <3312@ihlpf.ATT.COM> nevin1@ihlpf.UUCP (00704A-Liber,N.) writes: >(BTW, I really don't understand your 'use the >binary implementation of z ...' remark.) A fast way to implement a general integer-to-the-integer-power routine is to "think binary" about the exponent. If you can't figure out how this would work, I think it's shown in Gries' "The Science of Computer Programming".
gwyn@brl-smoke.ARPA (Doug Gwyn ) (01/09/88)
In article <7007@brl-smoke.ARPA> I wrote: >> a ^^ b >I think this is about as good a notation as we can get ... However, as Karl pointer out, this would make a good logical exclusive-or operator also, and I can see that the "strong argument" for exponentiation would also apply, somewhat more weakly, to exclusive-or, which I've often needed and have had to kludge ((a != 0) ^ (b != 0)). You see what a can of worms is opened up, once you start admitting extensions? Or, to mix metaphors, once you let a foot get in the door? > messy_expression ** 2 Of course this Fortran notation should be changed to whatever for the proposed C extension.
dant@tekla.TEK.COM (Dan Tilque;1893;92-789;LP=A;60aC) (01/09/88)
Stan Horwitz writes: > > One more comment about the power operator. So far most of the arguments >against it's use are reasonable, but not acceptable. If C can have an >operator for such as % for modulo divide, why not one for exponentiation? >Surely the same arguments against such a request can also be made against >the inclusion of %. Anyway, sorry to drag down the group with this topic. The historical reason for having modulo but not power is that C was originally a systems language. The modulo operator is much more useful that exponentiation for that purpose. Now that C is used for many different applications, perhaps it should be added. However, if it is added I think it should be restricted to having the exponent be an integer. If float exponents are desired, the user should have to invoke a library routine. --- Dan Tilque Now, if I could talk them into putting in a division operator which also returns the remainder (combined / and %)...
wong@llama.rtech.UUCP (J. Wong) (01/10/88)
In article <11169@brl-adm.ARPA> V4039%TEMPLEVM.BITNET@CUNYVM.CUNY.EDU (Stan Horwitz) writes: > >The question still stands. Why does C have no symbol to serve as a power >operator. There are so many symbols to use, and it would be easy to implement. One of the original motivations of the people who designed C was that no operation should result in a function call being generated in order to implement the language. Although, structure assignment and return might seem to violate this, it's true on some machines that they can be implemented through machine instructions. So, in general I think that the orginal motivation is still valid, and no operation (such as a power operator) should be introduced if the only way it can be implemented is through a function call. J. Wong ucbvax!mtxinu!rtech!wong **************************************************************** You start a conversation, you can't even finish it. You're talking alot, but you're not saying anything. When I have nothing to say, my lips are sealed. Say something once, why say it again. - David Byrne
bs@alice.UUCP (01/10/88)
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.
cik@l.cc.purdue.edu (Herman Rubin) (01/10/88)
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
edw@IUS1.CS.CMU.EDU (Eddie Wyatt) (01/11/88)
In article <1559@rtech.UUCP>, wong@llama.rtech.UUCP (J. Wong) writes: > One of the original motivations of the people who designed C was > that no operation should result in a function call being generated > in order to implement the language. Although, structure assignment > and return might seem to violate this, it's true on some machines > that they can be implemented through machine instructions. So, in > general I think that the orginal motivation is still valid, and no > operation (such as a power operator) should be introduced if the > only way it can be implemented is through a function call. > > J. Wong ucbvax!mtxinu!rtech!wong Actually any operation in a languge need not generate functions calls - have we heard of inline expansion? Assuming what you really meant was that there should be hardware support for the operation, well I don't think this case should be ruled by precedence. That is even if what you state was a design goal of the language. As I stand on my soap box .... Computer languages should be designed with providing a reasonable abstraction for a programming model while keeping in mind that the constructs used should be inexpensive to implement. I don't think anyone will question the reasonableness of an infixed notion for exponentiation. So the question remains is it too expensive to implement. On machines with hardware support, the answers should be no. In fact, it may be worst to use a function format because of some optimizations that can be realized when operands have special properties. These properties become harder to detect when using a functional format (integers must be typed coerced into doubles). On machines with no hardware support for exponetiation, the answer maybe one could do better with an fix notion then without it. Not only are the optimizations harder to detected with functional format, but also optimization coded by the programmer may have detrimental effects on timing. A classic of mine is the sqr(x) ((x)*(x)) macro. A seemingly harmless macro. When used in the context sqrt((double) sqr(x1-x2) + sqr(y1-y2)) you may start to realize its affects. The expressions (x1-x2) and (y1-y2) may be evaluated twice, that is unless the compiler does some common subexpression elimination. Aside : this last example illustrates a point I was trying to make to someone else about the side effects of macros. Some of the side effects macros may have are very illusive. -- Eddie Wyatt e-mail: edw@ius1.cs.cmu.edu
ix426@sdcc6.ucsd.EDU (tom stockfish) (01/11/88)
In article <5260001@hplsla.HP.COM> jima@hplsla.HP.COM ( Jim Adcock) writes: >Don't use ANSI-C, use C++, and overload the -> operator. >Then you can write: twoToTheTenth = 2.0->10.0; So when will C++ be available on enough machines that we numerical users can write in it and be assured of support when we change employers/machines? The C code that is emitted by CC is *not* portable, chiefly because things like getchar() are already expanded into their machine-specific inline code. Even if this problem could be gotten around, I would hate to have to maintain that C code. I like your choice for the operator. It seems to me this would work nicely if ANSI-C adopted it. It will *not* work for the example you give (2.0->10.0) because at least one operand of an overloaded operator must be a class object. (See Stroustrup's book p. 172). Supplying a trivial floating point class and supplying identity-operation constructors for it should do the trick, but you still won't be able to do constant -> constant without using a cast. If I'm wrong about this, or C++ has been extended to allow overloading of operators on basic types when the basic types don't have a normal meaning with an operator, I would like to hear about it. -- || Tom Stockfisch, UCSD Chemistry tps@chem.ucsd.edu
ok@quintus.UUCP (Richard A. O'Keefe) (01/11/88)
In article <1559@rtech.UUCP>, wong@llama.rtech.UUCP (J. Wong) writes: > One of the original motivations of the people who designed C was > that no operation should result in a function call being generated > in order to implement the language. On the PDP-11, not only did 32-bit integer *, /, and % generate subroutine calls, but C function entry and exit involved subroutine calls. These operations *could* have been performed by in-line code, but the space overhead would have been rather high. On quite a few machines the shift operators involve a function call when the shift count is not a constant. I hate to disillusion people (:-) but the plain fact is that the set of operators in C is (almost) identical to the set of operators in BCPL. There is one important exception: in BCPL the operators ~, &, and | are like !, &&, and || in "truth-value" context (argument of 'if', 'while', &c) or like ~, &, and | in "bit" context (assignment, argument passing). Here is a table in order of precedence: Construct BCPL C Constant 10, #47, #xFE 10, 047, 0xFE (examples) "string*N" 'c' "string\n" 'c' (expr) (expr) Cast {no types, not present} (type)expr Call expr(arg,...,arg) expr(arg,...,arg) Field field :: expr expr.field subscript array!wordoffset array[subscript] array%byteoffset {also array[subscript]} Address of @lvalue &lvalue Indirect !rvalue *rvalue Arithmetic e1 * e2 e1 * e2 e1 / e2 e1 / e2 e1 rem e2 e1 % e2 e1 + e2 e1 + e2 + e1 {omitted} e1 - e2 e1 - e2 - e1 - e1 Relational = ~= < <= > >= == != < <= > >= Shift << >> << >> Logical ~ ~ (bit context) {also ~} ! (truth-value context) & & and && | | and || e1 eqv e2 {use e1 ^~ e2} e1 neqv e2 e1 ^ e2 {^^ omitted} Conditional e1 -> e2, e3 e1 ? e2 : e3 Assignment e1 := e2 e1 = e2 Sequence e1 <> e2 e1, e2 The floating-point operations are (in the versions of BCPL that have them): #* #/ #+ #- #= #~= #<= #>= #< #> (no power operator!). Since everything is a "word", one has 36-bit integers and 36-bit floats, or 32-bit integers and 32-bit floats, or whatever. It is only at the statement and declaration level that C departs significantly from BCPL. In particular, C's switch() statement is almost identical to BCPL's SWITCHON(), except for one change that has never made sense to me. In BCPL, cases are terminated by ENDCASE, not by BREAK. So if you have a SWITCHON inside a loop, you can BREAK out of the loop without needing a goto. Confusing ENDCASE and BREAK has never made sense to me. Is there some deep reason for the choice of what is an operator and what isn't in BCPL? Almost certainly not, as it is a simplification of CPL which made so few concessions to hardware that I don't think it was ever fully implemented. I think the moral of it all is, go to the primary sources!
ok@quintus.UUCP (Richard A. O'Keefe) (01/11/88)
In article <622@PT.CS.CMU.EDU>, edw@IUS1.CS.CMU.EDU (Eddie Wyatt) writes: 1> Actually any operation in a languge need not generate functions calls - 1> have we heard of inline expansion? ... 2> implement. I don't think anyone will question the reasonableness 2> of an infixed notion for exponentiation. ... 3> properties become harder to detect when using a functional format 3> (integers must be typed coerced into doubles). On machines with 3> no hardware support for exponetiation, the answer maybe one could His points (1) and (3) contradict each other. In fact his point (3) is the direct opposite of C's defaults: at present, whenever you do X <operator> Y "the usual conversions" are done, which means amongst other things that if one operand is double, the other *will* be converted (which Wyatt says *won't* happen), whereas if you call a function integers will only be promoted to 'int'. In C, functional *syntax* gives us the freedom to have operands of different types: extern double pow(double base, double expt); -vs- extern double rtp(double base, int power); Note that these are quite different functions: rtp(-3.0, 2) is well defined, but pow(-3.0, 2.0) is illegal and should signal a matherr. (In Common Lisp, (EXPT -3.0 2.0) --> #C(9.0 0.0), a complex number.) Just to play devil's advocate, I'll question the reasonableness of an infix operator for exponentiation. Point 1: Many correspondents seem not to realise that there are TWO distinct operations (which happen to coincide for strictly positive bases). It would be unwise to provide special syntax for something so little understood. Point 2: At present, all the arithmetic operators apply "the usual conversions". Now the operation most commonly wanted is base ** k for k a constant integer expression, and base some size of float. The fact that k isn't (and mustn't) be converted makes "*%" unlike other operators. But there is nothing surprising about the function rtp(). Suppose we add an operator for pow(). This *would* apply "the usual conversions". Which means that if someone wrote "*$" when they really meant "*%" their program would appear to work when the base happened to be positive, though with some loss of precision. Point 3: Just what are the syntactic properties of "**"? I have used programming languages where it was left associative, where it was right associative, ones where "a ** -1" was legal, and ones where it wasn't (because unary minus had same precedence as infix -), and ones where "a ** -1" was legal but "a ** -j" was not. I deny that there is a single set of properties which all (or even most) programmers would agree on. Point 4: There is not the slightest reason why an operator should be "more efficient" than functional notation. In BCPL, one writes LET BLOCK = VEC 1000 IN $( statements $) whereas in C one writes { int *block = (int*)malloc(1000 * sizeof *block); statements } Does anyone reading this seriously suppose that the BCPL version is more efficient? Fortran uses functional syntax (MOD, IAND) where C uses operators (%, &). Does anyone seriously suppose that this makes a difference? Point 5: Inline expansion of pow() seems unwise unless the machine has an instruction to support it directly. Even if you have a floating-point chip which provides exp() and ln() instructions, *you should not use them*. To quote Cody & Waite, chapter 7: " The FORTRAN ** operator is defined mathematically as x ** y = exp(y * ln(x)) The obvious implementation of this definition using existing software for the exponential and logarithm functions results in large errors independent of those associated with the elementary function software used. ... The algorithms we present for this computation are far more complicated than any other algorithms presented in this manual." The 80287 and 80387 have "y * log2(x)" and "y * log2(x+1)" instructions, but these should only be used when that is the result you want. Using one of these instructions and then taking exp() is pretty much the combination Cody & Waite warn against. (These operations may use sufficient extra internal precision that you can get away with it, but I'd advise you to run the test program at the end of chapter 7.) This is not, of course, an argument against using an operator. The point is that pow() is a costly operation, which is going to be implemented as a subroutine on almost any existing machine, so why not be honest about it? Point 6: Not only is pow() costly, it is very rarely used even in number crunching programs. The saving is at best |pow(_,_)| - |_**_| = 4 characters. For this we should change the language? rtp() is another matter. But even that is pretty rare. I have some experience with numerical packages written in Fortran, and float**int was just not a common operation. In fact, I would claim that it is sufficiently rare that using a name for it rather than some exotic sequence of characters would make the code *more* readable and *more* maintainable. I wonder why no Pascal admirers have pointed out that Pascal *does* have a notation for what is far the commonest case, namely SQR(expr) = (expr)**2 Mind you, that is a very bad name for the operation, but it does exist. Given that the X3J11 is *standardising* C, not *inventing* it, leaving the two exponentiation operators out is the right thing for them to do. But we really should have the rtp() *operation* as well as pow().
wfp@dasys1.UUCP (William Phillips) (01/11/88)
If you really want an exponentiation operator in ANSI C (as it happens, I don't) here's a candidate: << I'm implementing a compiler for a special purpose language that looks a lot like C. The language spec that I was given specifies that the << and >> operators, when applied to floating point objects, act as exponentiation and inverse exponentiation operators; a logical sort of extension of right and left shifts of integer objects, isnt it? -- William Phillips {allegra,philabs,cmcl2}!phri\ Big Electric Cat Public Unix {bellcore,cmcl2}!cucard!dasys1!wfp New York, NY, USA (-: Just say "NO" to OS/2! :-)
eric@snark.UUCP (Eric S. Raymond) (01/12/88)
In article <7007@brl-smoke.ARPA>, Doug Gwyn writes: >In article <10026@ut-sally.UUCP> nather@ut-sally.UUCP (Ed Nather) writes: >> a ^^ b > >I think this is about as good a notation as we can get that is >compatible with existing code. I disagree. I can't look at ^^ and see anything but logical exclusive-or. Sigh. What happened to "no prior art"? -- Eric S. Raymond UUCP: {{seismo,ihnp4,rutgers}!cbmvax,sdcrdcf!burdvax,vu-vlsi}!snark!eric Post: 22 South Warren Avenue, Malvern, PA 19355 Phone: (215)-296-5718
jay@splut.UUCP (Jay Maynard) (01/12/88)
In article <6982@brl-smoke.ARPA>, gwyn@brl-smoke.ARPA (Doug Gwyn ) writes: > If someone wants to propose a good syntax for a built-in exponentiation > operator, send it in during the second public review of the draft > standard. [...] I must have missed how to do this...besides, I'm not a C guru (a barely-reformed Turbo Pascal hacker!)... > The x ** y syntax conflicts with existing C, which already ascribes > a different meaning to this, although I do think that anyone who has > been writing ** without a space in between deserves problems anyway. (my smart remark suppressed) Does anyone really write it this way, instead of x * *y? > x ^ y is also already taken. So it is. How about (WARNING: KLUDGE-O-MATIC OUTPUT COMING) : x *^ y Well, it was an idea...kinda gives the flavor of a multiplicative operation, and I don't think ^ is legal as a monadic operator... -- Jay Maynard, K5ZC (@WB5BBW)...>splut!< | GEnie: JAYMAYNARD CI$: 71036,1603 uucp: {uunet!nuchat,academ!uhnix1,{ihnp4,bellcore,killer}!tness1}!splut!jay Never ascribe to malice that which can adequately be explained by stupidity. The opinions herein are shared by none of my cats, much less anyone else.
jay@splut.UUCP (Jay Maynard) (01/12/88)
In article <326@splut.UUCP>, I wrote, as a suggested power operator: > x *^ y Unfortunately, due to newsfeed constipation, I wrote this before I saw someone-or-another's posting suggesting this very thing. Something about great minds... Then I got to thinking about the objections about putting a full-fledged exponentiator into the language as an operator. It struck me that it could be defined as analogous to % - only useful if the second operand is integer. That, in turn, raised another question: What does % do if you feed it something like x % 6.39? Maybe this idea ios getting better? Maybe worse? Like I said in the last message, I'm not a C guru - just a semi-converted Turbo Pascal hacker... -- Jay Maynard, K5ZC (@WB5BBW)...>splut!< | GEnie: JAYMAYNARD CI$: 71036,1603 uucp: {uunet!nuchat,academ!uhnix1,{ihnp4,bellcore,killer}!tness1}!splut!jay Never ascribe to malice that which can adequately be explained by stupidity. The opinions herein are shared by none of my cats, much less anyone else.
john13@garfield.UUCP (John Russell) (01/12/88)
In article <11169@brl-adm.ARPA> V4039%TEMPLEVM.BITNET@CUNYVM.CUNY.EDU (Stan Horwitz) writes: >The question still stands. Why does C have no symbol to serve as a power >operator. There are so many symbols to use, and it would be easy to implement. Because there are *so many* different ways to implement it, each optimal for specific cases. 2 ^ (int) with shifts; this is what I use most frequently and there _is_ an operator for it (<< and >>). (int) ^ (int) with various algorithms depending on the size of the exponent. (double) ^ (double) as pow() does it I rarely use, but you can see it requires a different approach to deal with the fractional exponent. John -- "Operating systems room, prepare for shutdown." "I never thought I'd be HAPPY to see our ratings do DOWN!" -- lots of these were sprinkled throughout the last broadcast episode of _Max_Headroom_
feg@clyde.ATT.COM (Forrest Gehrke) (01/13/88)
In article <7014@brl-smoke.ARPA>, gwyn@brl-smoke.ARPA (Doug Gwyn ) writes: > In article <7007@brl-smoke.ARPA> I wrote: > >> a ^^ b > >I think this is about as good a notation as we can get ... > > However, as Karl pointer out, this would make a good logical exclusive-or > operator also, and I can see that the "strong argument" for exponentiation > would also apply, somewhat more weakly, to exclusive-or, which I've often > needed and have had to kludge ((a != 0) ^ (b != 0)). > > You see what a can of worms is opened up, once you start admitting > extensions? Or, to mix metaphors, once you let a foot get in the door? If the argument for adding extensions is to avoid kludges, then let me be next in line: how about complex algebra notation (a + jb)? Exponentiation of complex variables could make good use of the exponent operator---and no one has mentioned root extraction yet. We could turn C into Ada++ overnight! Forrest Gehrke
franka@mmintl.UUCP (Frank Adams) (01/13/88)
In article <6982@brl-smoke.ARPA> gwyn@brl.arpa (Doug Gwyn (VLD/VMB) <gwyn>) writes: >If someone wants to propose a good syntax for a built-in exponentiation >operator, send it in during the second public review of the draft standard. I would vote for x ! y. It doesn't strike me as all that important a feature to add at this stage, though. Another thought: how about an #if pragma(name) construct, similar to #if defined(name), to test whether a pragma is defined by the implementation? -- Frank Adams ihnp4!philabs!pwa-b!mmintl!franka Ashton-Tate 52 Oakland Ave North E. Hartford, CT 06108
kurt@hi.unm.edu (Kurt Zeilenga) (01/13/88)
We had this plotting package here at UNM that has used the notation a#b to represent the expression a raised to the expression b. I always thought it was bizzarre, but then they are probably up the same proverbial creek. I think they should use '@' instead of '*' (the unary operator). This would free up '**' for the power operator. :-) -- Kurt (zeilenga@hc.dspo.gov)
nevin1@ihlpf.ATT.COM (00704A-Liber) (01/13/88)
In article <651@l.cc.purdue.edu> cik@l.cc.purdue.edu (Herman Rubin) writes: >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. Then the people you know do not know K&R C. Look in section 2.12 of K&R for precedence and order of associativity of operators; it is very well defined there. ('<<' and '..' are just below '+' and '-' (subtract, not minus) and both have left-to-right associativity.) Are you telling me that you *never* use the fact that multiplication has higher precedence than addition?? And without *any* definition of precedence, your compiler would have to flag expressions like 'a + b POWER c' (where 'POWER' is your power operator) as an error; it is ambiguous. Your addition would add ambiguity to a pretty unambiguous language (I KNOW I'll get flames for that last phrase :-)). > > .. .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. I said: .. 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 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. Since you, the programmer, know if the second argument is an integer, you can call a special routine (call it ipow(), for example) to implement your algorithm. C is very loosely typed and it does not permit the programmer himself to overload operators. Your application is very easy to define in a language like C++; it allows overloading of operators, inlining functions, and calling different routines based on different types. It is not necessary to expand C to C++; just USE C++ instead of C (and get this discussion out of here :-)). -- _ __ NEVIN J. LIBER ..!ihnp4!ihlpf!nevin1 (312) 510-6194 ' ) ) "The secret compartment of my ring I fill / / _ , __o ____ with an Underdog super-energy pill." / (_</_\/ <__/ / <_ These are solely MY opinions, not AT&T's, blah blah blah
tanner@ki4pv.uucp (Dr. T. Andrews) (01/14/88)
In article <7007@brl-smoke.ARPA>, gwyn@brl-smoke.UUCP writes: ) In article <10026@ut-sally.UUCP> nather@ut-sally.UUCP (Ed Nather) writes: ) > a ^^ b ) I think this is about as good a notation as we can get that is ) compatible with existing code. I fear that this would cause some confusion. While there is not CURRENTLY a "logical" xor operator, consider the following table: symbol op symbol op & b-and && l-and | b-or || l-or ^ b-xor ^^ power = cause equality == test equality (b-operation=bitwise; l-operation=logical) I don't know why there is no "logical" xor operation (same effect as ((op1 != 0)^(op2 != 0)) construction), but if one were to use the "^^" symbol, it would seem reasonable to expect it to yield a logical xor. Also, is that a kitchen sink I see hidden away under the rationale? Back behind that old stack of "codifying existing practice" bumper stickers? -- {allegra clyde!codas decvax!ucf-cs ihnp4!codas killer}!ki4pv!tanner
dam@mtgzz.UUCP (XMRN40000[kvm]-d.a.morano) (01/14/88)
In article <22773@hi.unm.edu>, kurt@hi.unm.edu (Kurt Zeilenga) writes: > I think they should use '@' instead of '*' (the unary > operator). This would free up '**' for the power operator. :-) Obviously, we can not change unary '*' to '@' and still have C, but this would have been an excellent choice for indirection back when K&R started to think about this. Those with a background of programming in DEC's assembly languages for the PDP-11 (and VAX) can appreciate this. As mentioned previously, the '**' can still be used for the power operator since the types of the operands can not be 'pointer to something'. In the following its use can be determined unambiguously when given a binary operator precedence : int a, *b, *c[], d ; d = a ** d ; d = a ***b ; /* is (a ** (*b)) */ d = *b****c ; /* although hard to see ((*b) ** (*(*c))) */ Dave Morano - AT&T
ray@micomvax.UUCP (Ray Dunn) (01/14/88)
In article <646@l.cc.purdue.edu> cik@l.cc.purdue.edu (Herman Rubin) writes: >> [ description of power function rather than power operator ] > >I think everyone should consider this unsatisfactory. > >One reason is that requiring the writing of a subroutine call is that >this requires people to use that notation instead of writing > > x = y ** z or x = y ! z. > >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. > Not all. POP-2 (An AI language from Edinburgh Univ) allows (simplified): operator <precedence> <operator name> ( <parameter list> ) as an option of <function name> ( <parameter list> ) to allow new operators to be defined. This together with the fact that you could define identifier names as combinations of signs ( e.g. *+*), was a very useful feature. >Another is that there are _several_ power functions; This is of course a contradiction to your statement above! Because there are several different versions is a very good reason to NOT have a power function built into the language as a standard operator. Which one should it be! No. Lets add the ability to define new infix operators in C instead (:-)! (Actually even the ability to define infixed pre-processor macros would add something ... just dreaming, not thinking!) Ray Dunn. ..philabs!micomvax!ray
gwyn@brl-smoke.ARPA (Doug Gwyn ) (01/14/88)
In article <3492@mtgzz.UUCP> dam@mtgzz.UUCP (XMRN40000[kvm]-d.a.morano) writes: >As mentioned previously, the '**' can still be used for >the power operator since the types of the operands can not be 'pointer to >something'. int a, *b, c; c = a ** b; /* means c = a * *b; */
peter@sugar.UUCP (Peter da Silva) (01/14/88)
C doesn't currently use @ or $, though some systems require that these symbols be valid in variable names. Also, since there is no short-circuit xor function (grin), you could use ^^. -- -- Peter da Silva `-_-' ...!hoptoad!academ!uhnix1!sugar!peter -- Disclaimer: These U aren't mere opinions... these are *values*.
halvers@iraq.steinmetz (peter c halverson) (01/14/88)
As long as we're asking for an exponentiation operator '**', what about hyperexponentiation? i.e. ... (y times) x x x n We could use '***'. Even better, why not generalize, and have * be the operator for the nth Ackermann's function? :-) :-) :-) :-) :-) :-) :-) :-) :-) :-) :-) :-) :-) :-) :-) :-) :-) :-) ~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~ Pete Halverson ARPA: halverson@ge-crd.ARPA General Electric Company UUCP: uunet!steinmetz!iraq!halvers Corporate R & D Schenectady, NY "Trust me; I know what I'm doing." --- Inspector Sledge Hammer
peter@sugar.UUCP (Peter da Silva) (01/15/88)
If the power operator is so important, how come Fortran includes all the mentioned variants of it as functions? It's handy, no denying that. Important enough to add to the language when the Fortran language committee still found that functional variants were needed, even though it's already in the language? I don't think so. -- -- Peter da Silva `-_-' ...!hoptoad!academ!uhnix1!sugar!peter -- Disclaimer: These U aren't mere opinions... these are *values*.
has@eagle.ukc.ac.uk (H.A.Shaw) (01/17/88)
Expires: Sender: Followup-To: This may look like a flame. It is not supposed to be, but I feel strongly that we are wasting our time with questions that have no relavence to C as a language. What people appear to be forgetting is what C is for. When I started to learn coding, the process of turning an algrothim into a real computer program, I was told that the first thing to do is to chose the language to use. You should not do complex mathematical work in C, in the same way that you don't solve simultainous equations in troff (I have seen this done!) if you want a long life without ulsers. What we need is to reduce C to it's basics. C is one of a nearly infinite group of languages, each is good at only ONE job. We have forgotten that C was originally a system programmers language. Who needs pow() in a pager or line printer demon? If you want maths, use FORTRAN, to teach, use BASIC/PASCAL, to drive a robot, use LOGO, etc., etc. Why do you think we have so many languages? The C language was a radical change from what went before it. There is still very little like it. It has a unique place in the scheme of things because of two very important principles that are buried deep in it. 1) The programmer knows what he is doing and it is none of the language's business to try and stop him. 2) Just because you *MAY* do something does not mean mean that you *SHOULD* do it. Therefore C allows things like: int a[], i; a[i++] = a[i++] + (int)&i + (int)&(a[i++]); or: struct one { int a, b;} var1; struct two { float c, d;} var2; var1.c = var2.b; If you are stupid enough to write such rubbish, then what business is it of the compiler to try and stop your madness. The intermable complaints about compiler dependent constructs are due to people trained on other languages not understanding principle 2) and the trust that a C compiler has in it's users. I was told to think of C as a macro-assemblier for the hardware you are on. It defines do{}while, for(){}, while(){} and switch(){} as macros in terms of "if" and "goto". A struct is just a name, and the elements within it are numeric offsets. Function calls are just JSR instructiuons with a bit of stack work first. (Therefore we get VARARGS etc. for free.) A variable is just a name with some memory behind it, you can reference it in any way you like. C is one of very few languages that has direct access to the addressing modes of the underlieing machine. Things like [i++], * and & are fine if you know the machine, and ALL C programmers are assumed to have infinite knowledge. As a final point, when I was an undergrad in Physics, the Computing Lab refused to teach C, as it was possible to pick up very bad habits from its freedom. We were told that programming was like walking. One should learn in a cushoned, small space before being let out into a big field where if you fall nobody will catch you. I wholeheartedly agree, and hope I write better C programs now for three years of BASIC/PASCAL/FORTRAN/FORTH first. They did teach it to third year Computer Scientists sometimes. PS: If hack had been written in DDL or something similar, would net.sources.bugs have all the traffic it now does? -- UUCP: ...seismo!mcvax!ukc!has | Howard A. Shaw. or : has@ukc.uucp | Room 12, Physics Lab., JANET: has@uk.ac.ukc | The University, Phone: +44 227 764000 Ext. 3282 | Canterbury, England. CT2 7NZ.
cik@l.cc.purdue.edu (Herman Rubin) (01/19/88)
In article <4186@eagle.ukc.ac.uk>, has@eagle.ukc.ac.uk (H.A.Shaw) writes: > This may look like a flame. It is not supposed to be, but I feel strongly > that we are wasting our time with questions that have no relavence to C as a > language. I have left out much of the original article. I hope I have not omitted anything important. > What people appear to be forgetting is what C is for. > You should not do complex mathematical work in C, > If you want maths, use FORTRAN, I find that I can do much better mathematical programming in C than in FORTRAN. By better programming, I mean that I can use constructs in C which are convenient and produce efficient code, and which FORTRAN does not know the first thing about. The only advantages of FORTRAN are the power operator and multi-dimensional arrays. The major disadvantages are the lack of indirection and casting, and the requirement that a function has an argument. Also C lets you use the rest of the instruction set (although it makes it difficult, sometimes very difficult). > 1) The programmer knows what he is doing and it is none > of the language's business to try and stop him. That is exactly what I am getting at. This is why C should attempt to be a flexible language, and if the programmer wants to use a useful construct, the language should at least allow it. > 2) Just because you *MAY* do something does not mean > mean that you *SHOULD* do it. Who decides what should be done? From comment 1), it must be the programmer! Therefore let the programmer do it! > I was told to think of C as a macro-assemblier for the hardware you are on. Then let that be done; that is what I want and do not find. > C is one of very few languages that has direct access to the addressing modes > of the underlieing machine. And this is not important in numerical analysis? > I wholeheartedly agree, and hope I write better C programs now for > three years of BASIC/PASCAL/FORTRAN/FORTH first. What would enable one to do a good programming job is to understand the machine first, so that one can know when the language is inadequate. I will modify my algorithm if the machine architecture calls for it. In a flexible language, most of the modifications can be indicated by comments. An example of an algorithm which should never have been programmed in C, and which should have been inline, is the infamous 4.2BSD frexp. That a construct is machine independent does not mean that its implementation should be. Actually, the power operator would be nearly machine independent; the major implementation differences would be where to stop treating special case of small integer exponents. In case you think that C++ should be used for some of these things, the answer is frequently _no_! If C++ were produced anew, it _might_ do a fair job. However, since it is a C preprocessor, whenever C produces bad code, it is likely to do worse. The language should help the programmer who knows the problem and the machine. -- 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
franka@mmintl.UUCP (Frank Adams) (01/19/88)
In article <2516@dasys1.UUCP> wfp@dasys1.UUCP (William Phillips) writes: >I'm implementing a compiler for a special purpose language that looks a lot >like C. The language spec that I was given specifies that the << and >> >operators, when applied to floating point objects, act as exponentiation >and inverse exponentiation operators; a logical sort of extension of >right and left shifts of integer objects, isnt it? No, it isn't. Besides the fact that under this interpretation 3 << 3 means something *entirely* different from 3.0 << 3, there is the fact that I want to raise integers to powers, too, not just floats. In fact, I believe that the single most common use of exponentiation, in languages which have operators for it, is to square an integer. (This is based only on my intuition, and obviously varies depending on the nature of the application.) If I were to apply a meaning to 3.0 << 3, it would be "3.0 times 2 to the third", or 24.0. Note that this is a function which many machines can implement with simple in-line code. -- Frank Adams ihnp4!philabs!pwa-b!mmintl!franka Ashton-Tate 52 Oakland Ave North E. Hartford, CT 06108
flaps@dgp.toronto.edu (Alan J Rosenthal) (01/19/88)
In article <3492@mtgzz.UUCP> dam@mtgzz.UUCP (XMRN40000[kvm]-d.a.morano) writes: >the '**' can still be used for the power operator since the types of >the operands cannot be 'pointer to something'. the lexer cannot determine this, so this is effectively operator overloading. rather a complication to introduce into C at this time just to provide a slight syntactic advantage for an obscure operator. -- "noalias considered sailaon"
gwyn@brl-smoke.ARPA (Doug Gwyn ) (01/19/88)
In article <4186@eagle.ukc.ac.uk> has@ukc.ac.uk (H.A.Shaw) writes: >You should not do complex mathematical work in C, ... I've been involved in several large "scientific" applications that for one reason or another were written in C, including one undergoing coding at this very moment. There is no way that any of them would have been feasible in Fortran, which lacks support for data structures, dynamic memory allocation, interface specification files (headers), and other essential features that C provides. I used to be quite proficient in Fortran, and even did "systems programming" in it (yes, it was painful), but I've never found a need to revert to Fortran now that I have C to use. > If hack had been written in DDL or something similar, would >net.sources.bugs have all the traffic it now does? Hack's problems are not due to the language it is written in, but to the fact that it was developed by amateurs. Even a cursory examination of its source code shows that its authors were not in command of the language.
karl@haddock.ISC.COM (Karl Heuer) (01/20/88)
In article <2649@mmintl.UUCP> franka@mmintl.UUCP (Frank Adams) writes: >[If there should be a power operator,] I would vote for x ! y. As I pointed out in a previous article, that doesn't allow for a corresponding compound assignment operator (since "!=" is taken). Besides, it seems a waste to use a one-character operator for something so seldom necessary. Karl W. Z. Heuer (ima!haddock!karl or karl@haddock.isc.com), The Walking Lint
ix426@sdcc6.ucsd.EDU (tom stockfish) (01/20/88)
In article <4186@eagle.ukc.ac.uk> has@ukc.ac.uk (H.A.Shaw) writes: >What people appear to be forgetting is what C is for.... >You >should not do complex mathematical work in C, in the same way that you don't >solve simultainous equations in troff (I have seen this done!) if you want a >long life without ulsers. What we need is to reduce C to it's basics. C is >one of a nearly infinite group of languages, each is good at only ONE job. We >have forgotten that C was originally a system programmers language. Who needs >pow() in a pager or line printer demon? If you want maths, use FORTRAN, to >teach, use BASIC/PASCAL, to drive a robot, use LOGO, etc., etc. Why do you >think we have so many languages? The problem is, there are a million reasons *not* to use fortran for numeric work. For instance, on a machine running Berkely unix, 1. f77 compiles about 50% slower than cc, on comparable source code. 2. on a Celerity, the famous "hello world\n" program, in C, has a 30kbytes executable file (stripped), whereas the fortran version is 100kbytes! Essentially every fortran executable is 70kbytes larger than the equivalent program in C. 3. You can't reasonably write user-friendly i/o schemes for numeric work in fortran. In C you can do a lot of very nice stuff with lex and yacc. 4. In Unix, fortran users are second-class citizens. The symbolic debugger (dbx) is almost unusable with fortran. There are two beautifier programs for C (cb and indent), none for fortran. Other system utilities, such as awk, bc, and sh borrow much of there syntax from C. If there is something wrong with the C compiler it gets instant attention, because the whole system depends on it. For instance, a colleague's research ground to a halt when we upgraded from 4.1bsd to 4.2. NONE of his programs worked anymore, because "print *, ..." statements no longer worked. I doubt a "bug" of such magnitude would have been allowed to slip out in the C compiler. 5. fortran, compared to C, is a very nasty language to write in. The only time I do is when I need complex arithmetic, and then, I write only those subroutines I need in it. When C++ compilers become widespread, I won't use fortran ever again. (At that time I won't use C ever again, but that's another story). 6. On PC's, C compilers are cheap and readily available. Fortran compilers are expensive and might not fit on your machine. Anyway, back to the issue, which is additions to the C standard to make numeric work on C attractive. I realize that system programmers can't live with inside-parenthesis-only optimizations, and that numeric people will never muck up there already difficult to read mathematical expressions with a zillion more parentheses and unary plusses. That is why I whole-heartedly support the previously proposed use of []'s to mean groupings which cannot be rearranged. It's orthogonal, it's mathematical looking, it's elegant, it overloads []'s no more than parentheses are already overloaded, it's [insert your favorite buzzword]. If a power operator is too much trouble, o.k., forget it. But this evaluation order thing is crucial. I wish there were a language designed just for numerical work that was better than C. But nothing comes close. -- || Tom Stockfisch, UCSD Chemistry tps@chem.ucsd.edu
dsill@NSWC-OAS.arpa (Dave Sill) (01/20/88)
In article <658@l.cc.purdue.edu> Herman Rubin <cik@l.cc.purdue.EDU> writes: >... The only advantages of FORTRAN are the power operator and >multi-dimensional arrays. ... Huh? >In case you think that C++ should be used for some of these things, the answer >is frequently _no_! If C++ were produced anew, it _might_ do a fair job. >However, since it is a C preprocessor, whenever C produces bad code, it is >likely to do worse. Strickly speaking, C++ is a compiler, not a preprocessor. However, your point that the quality of C++ code depends on the quality of the C compiler still stands. That's not a fault of C++, though. It's a truism that the performance of an application depends on the software that compiled it. By the way, GNU's version of C++, G++, doesn't generate C code. It generates object code directly. That doesn't mean it's any better than C++, because it really just has a built-in C compiler. ========= The opinions expressed above are mine. "I shed, therefore, I am." -- ALF