Path: utzoo!utgpu!water!watmath!clyde!rutgers!rochester!quiroz From: quiroz@cs.rochester.edu (Cesar Quiroz) Newsgroups: comp.lang.c Subject: Re: pow again (Complex valued or partially defined?) Message-ID: <5825@sol.ARPA> Date: 12 Jan 88 21:15:13 GMT References: <629@PT.CS.CMU.EDU> Reply-To: quiroz@ROCHESTER.UUCP (Cesar Quiroz) Organization: U of Rochester, CS Dept, Rochester, NY Lines: 90 Expires: Sender: Followup-To: Abstract-- There is no such thing as a unique, universally accepted definition for the exponentiation. The case of expt0: RealxInteger->Real is different (in a mathematical way and from optimization perspectives) from the one of expt1: RealxReal->Complex There is no such thing as a satisfactory expt-: RealxReal->Real C may either have two functions (pow for expt1 and the proposed rtp for expt0) or have an operator that lets the compiler choose statically between the two. In either case, pow has to be partially defined, because of the lack of complex arithmetic in the base language. As C doesn't support complex arithmetic directly, we currently cannot do things like making sqrt return complex values for the negatives and real values for the positives. Instead, we just make it set EDOM and be happy with it for a negative argument. Actually, even if we had complex arithmetic, we wouldn't want it to return differently typed results in different domains (a matter of taste) so we would be burdened with either returning always complex numbers (complicating the common case) or keeping with the EDOM error. Why did I bring sqrt in here? Because the error domain of the real valued sqrt is well accepted: all the negatives. With pow we don't have that benefit. O'Keefe explained this recently, but Wyatt missed the point completely. In a sentence, *there is more than one possible exponentiation function*. We cannot just have an operator that fails to compute pow on all the negative bases, because the basic definition of exponentiation is that of `repeated multiplication'. So, there are some people who would rightly desire (pow(-2.0,3) == -8.0) to be true. Regrettably, they cannot provide any meaningful value for pow(-2.0, 3.1), so they might want to settle for EDOM or a complex result. The most accepted (and perhaps most acceptable) extension of the repeated multiplication definition, that provides meaning for all combinations of bases and exponents, is the one embedded in Common Lisp's EXPT function. Wyatt, and other people interested in how it works, are referred to Steele's "Common Lisp: The Language". Wyatt seems to believe the choice of such definition was whimsical and that other languages could `choose' otherwise. Actually, he is almost right, in that doing the right thing in C requires many more changes to the language than is worth doing in the coming Standard. Common Lisp `did it right'. There is a rule of complex canonicalization, that lets you identify #C(12 0) with 12 (rationals, nor floats, all over). The natural extension to this rule is to permit their sqrt to return sensible things in the positive and negative domains. The same happens with expt, it is defined in such a way that it is permissible to do intelligent things with rational exponents and this does not break any semantic properties of the rest of the language. But this is possible due to the polymorphism of Lisp functions and their ability to query the types of their arguments (remember that typeof discussion?) The EXPT solution cannot be implemented in C, however, because C functions cannot compute the types of their arguments. This out of the way, there is still the lesser problem of not having complex arithmetic. All in all, I don't think C as now exists can host a decent implementation of exponentiation as a single function. It might still be convenient to optimize the common case of an integer exponent (to use the repeated multiplication rule) and then the rtp function proposed by O'Keefe comes handy. No need for an independent operator, at least not until a time comes to make more radical changes to the language. Some one (sorry, I didn't keep the article) already said that a new operator is not an isolated change, but would require other compatible changes, to avoid kludginess. (For instance, a corresponding assignment). I hope people who want to introduce exponentiation ops in C are willing to do it right and therefore will refrain from giving the ANSI committee a reason to invent a new feature without prior art. People interested in the problems of embedding exponentiation in a language without complex arithmetic are invited to follow up to comp.lang.misc or correspond by Email, I will be happy to participate in such discussion. (Past experience makes me add this: If you don't know why it is true that RealxReal and Complex are *not* the same structure, please figure that out first.) -- Cesar Augusto Quiroz Gonzalez Department of Computer Science ...allegra!rochester!quiroz University of Rochester or Rochester, NY 14627 quiroz@cs.rochester.edu