Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Power operator! for C++

63 views
Skip to first unread message

John (MAX) Skaller

unread,
Jun 26, 1992, 3:47:42 PM6/26/92
to
This is an *informal* proposal for an extension to C++.

The proposal is to add binary operator ! to the language.

The meaning of

a ! b

will be the same as

pow(a,b)

The operator will associate right to left.

The precedence will be :

! binds tighter than *
! binds looser than ->*

That means the meaning of

-a!b

is
-(a!b)

DISCUSSION:

Only two existing tokens are available for
use as binary operators, ! and ~.

! has the advantage that it looks much like an upward arrow.
Its prefix form is an arithmetic operator already.

~ is a bitwise operator and hard to type on many keyboards.

There is no choice about the precedence or associativity.

The semantics are questionable. The definition I have
used makes the operator trivial to implement,
It can convert both arguments to double and return a double.

[Returning int for int arguments does not make sense
except in special cases. The loss of this ability
permanently would be damaging if there were a better
definition of the semantics later.]

Because this extension is effectively an extension to C
not C++, there are implications for the C community as well.

While *personally* I don't care, this is an important
point.

---------------------------------------------------------

If you like this proposal SAY SOMETHING or it will die.

If you don't, ALSO say something. Please.
[ESPECIALLY if you happen to be a member of ANSI :-)

----------------------------------------------------

And support the formation of an ANSI/net interface
newsgroup. Or shoot it down.

--
;----------------------------------------------------------------------
JOHN (MAX) SKALLER, max...@extro.ucc.su.oz.au
Maxtal Pty Ltd, 6 MacKay St ASHFIELD, NSW 2131, AUSTRALIA
;--------------- SCIENTIFIC AND ENGINEERING SOFTWARE ------------------

Matt Austern

unread,
Jun 26, 1992, 2:37:14 PM6/26/92
to
In article <1992Jun26.1...@ucc.su.OZ.AU> max...@extro.ucc.su.OZ.AU (John (MAX) Skaller) writes:

> This is an *informal* proposal for an extension to C++.
>
> The proposal is to add binary operator ! to the language.
>
> The meaning of
>
> a ! b
>
> will be the same as
>
> pow(a,b)
>

A small addendum: if n is an integer, then a ! n should not mean the
same as pow(a,n). This is for two reasons:
(1) It is possible to compute a ! n much more efficiently if
n is an integer than if it is a floating-point number.
(This is one of the main reasons why an exponentiation
operator is such a good idea.)
(2) There is a slight mathematical difference. If a is negative,
and b is a real number, then a ! b is complex; however, if
n is an integer, then a ! n can be defined to be real.

Otherwise, I think this is a good idea. I don't know what the
official ANSI requirements are for an extension (I, also, would like
to hear from the folks on the committee who are reading this), but it
meets what I consider to be the important requirements:
(1) There is a great deal of prior art: every language with
infix operators, other than C, has an exponentiation
operator.
(2) It is trivial to implement.
(3) It does not break any existing code, in either C or C++.
Binary ! is undefined in both languages.
(4) It imposes no burden at all on programs or programmers
that don't use it.
(5) It is very important to a significant number of people.
The absence of an exponentiation operator is a nuisance
for scientific programmers who use C++, and it is a
further entry barrier for scientific programmers who
are currently using a differently language, and who might
otherwise want to switch to C++.


--
Matthew Austern I dreamt I was being followed by a roving band of
(510) 644-2618 of young Republicans, all wearing the same suit,
ma...@physics.berkeley.edu taunting me and shouting, "Politically correct
aus...@theorm.lbl.gov multiculturist scum!"... They were going to make
aus...@lbl.bitnet me kiss Jesse Helms's picture when I woke up.

John (MAX) Skaller

unread,
Jun 26, 1992, 3:53:33 PM6/26/92
to
In article <1992Jun26.1...@ucc.su.OZ.AU> max...@extro.ucc.su.OZ.AU (John (MAX) Skaller) writes:
> This is an *informal* proposal for an extension to C++.
>
> The proposal is to add binary operator ! to the language.
>
> The meaning of
>
> a ! b
>
> will be the same as
>
> pow(a,b)
>
> The operator will associate right to left.
>
> The precedence will be :
>
> ! binds tighter than *
> ! binds looser than ->*
>
> That means the meaning of
>
> -a!b
>
> is
> -(a!b)


WOOPS: correction:

(-a) ! b

Ronald Schoenberg

unread,
Jun 27, 1992, 1:55:19 PM6/27/92
to
In article <1992Jun26.1...@ucc.su.OZ.AU> max...@extro.ucc.su.OZ.AU (John (MAX) Skaller) writes:
> This is an *informal* proposal for an extension to C++.
>
> The proposal is to add binary operator ! to the language.
>
.
. elided material

.
>
> ---------------------------------------------------------
>
> If you like this proposal SAY SOMETHING or it will die.
>
> If you don't, ALSO say something. Please.
> [ESPECIALLY if you happen to be a member of ANSI :-)
>
> ----------------------------------------------------
>
> And support the formation of an ANSI/net interface
> newsgroup. Or shoot it down.
>
>--
>;----------------------------------------------------------------------
> JOHN (MAX) SKALLER, max...@extro.ucc.su.oz.au
> Maxtal Pty Ltd, 6 MacKay St ASHFIELD, NSW 2131, AUSTRALIA
>;--------------- SCIENTIFIC AND ENGINEERING SOFTWARE ------------------


I most emphatically support the above and if there is anything more I
can do please let me know.

John (MAX) Skaller

unread,
Jun 27, 1992, 1:25:13 PM6/27/92
to

>A small addendum: if n is an integer, then a ! n should not mean the
>same as pow(a,n). This is for two reasons:
> (1) It is possible to compute a ! n much more efficiently if
> n is an integer than if it is a floating-point number.
> (This is one of the main reasons why an exponentiation
> operator is such a good idea.)

And even more efficiently if a is an integer too!
I do not know how to specify the semantics so that
the compiler can optimise.

However, I think the formal specification should require
double arguments and return type. If the compiler can optimise
that, well and good: the pow(double,double) function can do
that too, except that an extra conversion would be needed
on the return type.

> (2) There is a slight mathematical difference. If a is negative,
> and b is a real number, then a ! b is complex; however, if
> n is an integer, then a ! n can be defined to be real.

C++ has no complex type.

Therefore, I suggest that any complex answer would be an
error, just as in pow.

This can be overcome with a complex class by overloading.
It would require ONE of the operands to be cast to
complex though.

However, the compiler cannot know the values of the numbers
so the test on a being negative cannot be used to discriminate
return types.

Proposed Amendment 1:
-------------------

To be decided separately.

If the second argument is an integer then a ! n can
be optimised by the compiler.


Proposed Amendment 2:
---------------------

Instead of returning an error when a complex result is
produced, a ! b will return the real part.
The compiler will issue a warning, except when the second
argument is an integer.

>
>Otherwise, I think this is a good idea. I don't know what the
>official ANSI requirements are for an extension

This can be dealt with later when we have a reasonable
consenus.

It would help if my proposed net/ANSI interface newsgroup
were created. Please support! Discussion is needed or
it and most net-proposed extensions, will die.


>(I, also, would like
>to hear from the folks on the committee who are reading this), but it
>meets what I consider to be the important requirements:

> (1) There is a great deal of prior art: every language with
> infix operators, other than C, has an exponentiation
> operator.

[Does Pascal?]

> (2) It is trivial to implement.

[at least in my original proposal a call to pow would be
sufficient]

> (3) It does not break any existing code, in either C or C++.
> Binary ! is undefined in both languages.

[But there are implications for C. Should be cross post
this to comp.std.c++ and comp.lang.c?]

> (4) It imposes no burden at all on programs or programmers
> that don't use it.

> (5) It is very important to a significant number of people.
> The absence of an exponentiation operator is a nuisance
> for scientific programmers who use C++, and it is a
> further entry barrier for scientific programmers who
> are currently using a differently language, and who might
> otherwise want to switch to C++.
>

[6] It also makes another overloadable operator available.


>
>--
>Matthew Austern I dreamt I was being followed by a roving band of
>(510) 644-2618 of young Republicans, all wearing the same suit,
>ma...@physics.berkeley.edu taunting me and shouting, "Politically correct
>aus...@theorm.lbl.gov multiculturist scum!"... They were going to make
>aus...@lbl.bitnet me kiss Jesse Helms's picture when I woke up.

Matt Austern

unread,
Jun 27, 1992, 9:26:43 AM6/27/92
to
In article <1992Jun27.1...@ucc.su.OZ.AU> max...@extro.ucc.su.OZ.AU (John (MAX) Skaller) writes:

> >A small addendum: if n is an integer, then a ! n should not mean the
> >same as pow(a,n). This is for two reasons:

> > (2) There is a slight mathematical difference. If a is negative,
> > and b is a real number, then a ! b is complex; however, if
> > n is an integer, then a ! n can be defined to be real.
>
> C++ has no complex type.
>
> Therefore, I suggest that any complex answer would be an
> error, just as in pow.

Yes. This is what I had in mind; I suppose I wasn't explicit. What I
mean is that the expression (-3.2) ! 2.3 is an error, just like
pow(-3.2, 2.3), sqrt(-2.), or 1./0., and that it should be treated as a
run-time error.

However, the expressions (-2.3) ! 2 is *not* an error: taking the
square of a negative number is a completely legitimate operation. Any
proposal for allowing exponentiation in C++ should certainly allow
squaring (and cubing, and...) negative numbers.

Ronald Bodkin

unread,
Jun 27, 1992, 10:12:13 PM6/27/92
to
In article <1992Jun27.1...@ucc.su.OZ.AU> max...@extro.ucc.su.OZ.AU (John (MAX) Skaller) writes:
Proposed Amendment 1:
-------------------

To be decided separately.

If the second argument is an integer then a ! n can
be optimised by the compiler.

I'm not sure why you wouldn't just define operator!(double x, double y)
and operator!(double x, int y) to have different semantics. I'm also
a little bit unsure how one can resolve the problem of efficiently
computing integer exponents. Consider this way of "implementing"
operator!:

double operator!(double x, double y) { return pow(x,y); }

double operator!(double x, int y) {
if (y<0)
return 1.0/(x!(-y));
else {
double v=1.0;
while (y--)
v*=x;
return v;
}
}

The "right" way to compute x!4 is to factor, i.e.:
v=x*x;
return v*v;

i.e. x!4==(x!2)!2, and likewise x!5==(x!2)!2*x. But unlike
optimizations of this kind for multiplication of two integers, here
the value returned depends on the particular optimization technique
(since floating point multiplication is not generally associative).

Ron

Matt Austern

unread,
Jun 27, 1992, 2:26:28 PM6/27/92
to

> I'm not sure why you wouldn't just define operator!(double x, double y)
> and operator!(double x, int y) to have different semantics. I'm also
> a little bit unsure how one can resolve the problem of efficiently
> computing integer exponents.

I agree that operator!(double, double) and operator!(double, int) should
have different semantics. (I see no reason, however, to take the
trouble to define operator!(int, int) separately.)

Both efficiency and precision are "quality of implementation" issues,
and I see no reason to address them in the Standard. (I would imagine
that given the expression x!n, where n is a small integer known at
compile time, a good compiler would not call a function at all, but
just do a couple of multiplications.)

In any case, though, these problems have all been dealt with before;
Fortran compilers have been dealing with the problem of efficient and
accurate computation of exponentiation for many years.

Doug Moore

unread,
Jun 27, 1992, 10:08:20 PM6/27/92
to
I wish to strongly support the idea of a power operator for C++.
However, I object to the use of '!' for that operator. Binary
operators in C and C++ usually have assignment forms, so that

a op= b

has (ignoring side effects in the evaluation of a) the same meaning as

a = a op b

However, for the proposed operator, the expression

a != b

would most certainly not be the same as a = a!b. Therefore, I suggest
that tilde (~) is a better alternative.

Doug Moore
(do...@cs.rice.edu)

David Cok

unread,
Jun 27, 1992, 10:37:52 PM6/27/92
to
In article <MATT.92Ju...@physics2.berkeley.edu> ma...@physics.berkeley.edu writes:
>I agree that operator!(double, double) and operator!(double, int) should
>have different semantics. (I see no reason, however, to take the
>trouble to define operator!(int, int) separately.)
>
I do. I think that operator!(int,int) should return an int and that
both operator!(double,int) and operator!(double,double) should return double.
This would match the way that other arithmetic operators on numeric types
work.

>--
>Matthew Austern I dreamt I was being followed by a roving band of
>(510) 644-2618 of young Republicans, all wearing the same suit,
>ma...@physics.berkeley.edu taunting me and shouting, "Politically correct
>aus...@theorm.lbl.gov multiculturist scum!"... They were going to make
>aus...@lbl.bitnet me kiss Jesse Helms's picture when I woke up.


David Cok
Eastman Kodak Company
c...@Kodak.COM

John (MAX) Skaller

unread,
Jun 28, 1992, 4:31:57 AM6/28/92
to
>In article <1992Jun27.1...@ucc.su.OZ.AU> max...@extro.ucc.su.OZ.AU (John (MAX) Skaller) writes:
> Proposed Amendment 1:
> -------------------
>
> To be decided separately.
>
> If the second argument is an integer then a ! n can
> be optimised by the compiler.
>
>I'm not sure why you wouldn't just define operator!(double x, double y)
>and operator!(double x, int y) to have different semantics.

Neither am I, which is why the amendment.

>I'm also
>a little bit unsure how one can resolve the problem of efficiently
>computing integer exponents. Consider this way of "implementing"
>operator!:
>

[two methods of optimising pow deleted]

>i.e. x!4==(x!2)!2, and likewise x!5==(x!2)!2*x. But unlike
>optimizations of this kind for multiplication of two integers, here
>the value returned depends on the particular optimization technique
>(since floating point multiplication is not generally associative).
>
> Ron

The problem is the specification of how accurate the answer
must be. IS there such a spec for existing math functions?

I can't see a good argument against having just

a ! b == pow(a,b)

because 'optimisation' is the job of the compiler.
IF there were separate language definitions for

a ! b
a ! n

then the only consequence would be that in some header file
predefined names would indicate the accuracy of the
answer somehow.

On the 486, for example, the result of the FP instruction
pow(a,b) might well be MORE accurate than some faster
technique using multiply. In fact it is almost certain
to be the case, since I think the 486 FPU makes certain
guarantees about accurace (up to the last bit or something,
I haven't actually checked). It does all FP calculations
in extended double precision anyhow.

So the reason for this being an amendment is that I
suspect specification of the pow function is limited
syntactically to saying

a ! b computes a raised to the power of b

without any indication of how accurately, that being
machine dependent (and compiler dependent) anyhow.
What is the position with 'pow'? What about 'sin'?
More to the point, what about '/', how accurate is
that guaranteed to be?

Anyhow, I would be inclined to reject the amendment
because saying

"a ! b is equivalent to pow(a,b)"

doesn't say anything much anyhow. All it says it that
a compiler that replaces a!b with pow(a,b) would
conform to the standard. A compiler that was
smarter might ALSO comform. I would not even
want to insist that 2 squared was 4, after all,
in floating point equality is not a legal operation
really!

John (MAX) Skaller

unread,
Jun 28, 1992, 4:56:25 AM6/28/92
to


I didn't think of that!
It is a very strong argument.

Amendment 4
-----------

Use ~ for the power operator,
and also allow ~= for assignment.

Matt Austern

unread,
Jun 28, 1992, 8:39:06 AM6/28/92
to
In article <1992Jun28....@ucc.su.OZ.AU> max...@extro.ucc.su.OZ.AU (John (MAX) Skaller) writes:

> >I agree that operator!(double, double) and operator!(double, int) should
> >have different semantics.
>

> Why different semantics? Mathematically it is the same!
> Why is this not also an implementation issue?

Well, it really isn't the same mathematically. Again: the issue is
what happens when the first argument is negative.

Squaring a negative number is a well-defined mathematical operation,
and computer languages ought to permit it. I would be very disturbed
if I got a run-time error from trying to compute (-3.)!2. By
contrast, raising a negative number to a non-integral power is very
different, and the only correct thing to do with, for example,
(-1.)^(0.5), is to signal an error.

Mathematically, then, x!y and x!n are not the same, and they should
not be treated the same by a computer language. Certainly existing
languages (e.g., Fortran) do not treat them the same, and I believe
that C++ should conform to existing practice.

One of the main uses of a power operator is raising a number to a
small integral power. If operator! doesn't allow this, or if it
allows it only if that number is positive, then it is so badly broken
that it will be almost useless.

Ronald Bodkin

unread,
Jun 28, 1992, 5:03:29 PM6/28/92
to
In article <1992Jun28....@kodak.kodak.com> c...@sunshine.Kodak.COM (David Cok) writes:
I do. I think that operator!(int,int) should return an int...

Unfortunately n!-m (m>0, n>1) is NOT an int! For example 2!-1
is 0.5. So you have to return a rational, and we don't have
rationals, so doubles will have to do.
Ron

Hallvard B Furuseth

unread,
Jun 28, 1992, 10:11:48 PM6/28/92
to

> Unfortunately n!-m (m>0, n>1) is NOT an int! For example 2!-1
> is 0.5. So you have to return a rational, and we don't have
> rationals, so doubles will have to do.

If you want a int!-1 to be rational, cast it to double. Just as with
integer division.
--

Hallvard

Dag Bruck

unread,
Jun 29, 1992, 2:28:58 AM6/29/92
to

Do you think exceptions should be used for reporting an error?
If so, why? If not so, why?

Matti Nykanen

unread,
Jun 29, 1992, 7:34:52 AM6/29/92
to
In <MATT.92Ju...@physics2.berkeley.edu> ma...@physics2.berkeley.edu (Matt Austern) writes:
:

>Squaring a negative number is a well-defined mathematical operation,
>and computer languages ought to permit it. I would be very disturbed
>if I got a run-time error from trying to compute (-3.)!2. By
>contrast, raising a negative number to a non-integral power is very
>different, and the only correct thing to do with, for example,
>(-1.)^(0.5), is to signal an error.
:

>One of the main uses of a power operator is raising a number to a
>small integral power. If operator! doesn't allow this, or if it
>allows it only if that number is positive, then it is so badly broken
>that it will be almost useless.

That's why I like the idea of differentiating between the cases..
BASE POWER RESULT
double double double
double int double
int unsigned int
but omitting the problematic case (What if the power<0? What if both are?)
int int int? double? complex? error?
The compilers already carry out this type of analysis when inferring the
type and necessary casts in arithmetic expressions. Note however that
some "counterintuitive" results follow, e.g. 3!2 is promoted to 3.0!2=9.0,
because the integer constant 2 cannot be "demoted" to (unsigned)2 to
give 9 as integer.

P.S. The above should NOT be taken as endorsing the use of ! as the
notation, however..
--

Internet: Matti....@Helsinki.FI Department of Computer Science
Phone : +358 0 708 4207 University of Helsinki,Finland

Hallvard B Furuseth

unread,
Jun 29, 1992, 11:22:56 AM6/29/92
to
In article <1992Jun29....@lth.se> d...@control.lth.se (Dag Bruck) writes:

> Do you think exceptions should be used for reporting an error?

No. I wrote "just as with integer division" and that's what I meant.
Just truncate the result.

> If so, why? If not so, why?

I want it to be close to Fortran. Its designers know (hopefully) more
about such issues than most of us C(++) people.

int!-unsigned does not seem very useful to me so why make it
complicated.

I want strange user input to give strange answers, not to dump core or
to force the programmer to check for all sorts of special cases.


If you absolutely want something to worry about: Should int~-unsigned
truncate towards zero, fortranish and predictable, or should we require
int(foo)^^-1 == 1/int(foo)?

I don't care, I'd be satisfied to let the implementor choose.
Do you know any Fortran programmers who raise integers to negative
powers anyway? I suppose it could be a nice trick for getting rid of
A*x!i terms, but I'd prefer to set A to 0.
--

Regards,

Hallvard

John (MAX) Skaller

unread,
Jun 29, 1992, 12:08:09 PM6/29/92
to
>In article <1992Jun28....@ucc.su.OZ.AU> max...@extro.ucc.su.OZ.AU (John (MAX) Skaller) writes:
>
>> >I agree that operator!(double, double) and operator!(double, int) should
>> >have different semantics.
>>
>> Why different semantics? Mathematically it is the same!
>> Why is this not also an implementation issue?
>
>Well, it really isn't the same mathematically. Again: the issue is
>what happens when the first argument is negative.
>
>Squaring a negative number is a well-defined mathematical operation,
>and computer languages ought to permit it. I would be very disturbed
>if I got a run-time error from trying to compute (-3.)!2. By
>contrast, raising a negative number to a non-integral power is very
>different, and the only correct thing to do with, for example,
>(-1.)^(0.5), is to signal an error.
>
>Mathematically, then, x!y and x!n are not the same, and they should
>not be treated the same by a computer language. Certainly existing
>languages (e.g., Fortran) do not treat them the same, and I believe
>that C++ should conform to existing practice.
>
>One of the main uses of a power operator is raising a number to a
>small integral power. If operator! doesn't allow this, or if it
>allows it only if that number is positive, then it is so badly broken
>that it will be almost useless.
>--

I stand corrected.

I do not think lack of a!n (or is it a~n ??) would make
it useless.

I will try to summarise the rules for power, someone
please confirm or correct me:

Consider a raised to power of b.

1) If a and b are real and a is positive, the result is real
and positiive.

2) If a is negative, the result in general is complex.

3) If a is real negative and b integral, the result
is real.

4) If a is integral and b positive integral, the result
is integral.

There are various approaches to the implementation, and this
is the basic problem with any proposal.

The simplest, to use only two double arguments and chuck an error
if the result appear complex amounts to:

a ! b is well defined if a>0

and there are two approaches is a<0, one can either always
give a domain error, or give an error if the result is complex.
The latter would be implementation dependent.

Extending the language to allow b integral as a special case
fixes this, but at the expense of having an operator where
promotion of the second argument from integral to floating
would not be legal, it would be the only operator like
this (most binary operators (all?) insist on two
arguments of the same type).

The second argument could not be 'int', since then 'long'
would convert to double. But if it were 'long', what
would happen to 'unsigned long'? That would have to
be a separately defined operation as well (to stop
it converting to double)

The same sort of problem occurs if we want integers raised
to integer powers giving an integer result. Converting
signed to unsigned quantities of the same type must
not be allowed, so a spec like
unsigned long ~ unsigned long
could not stand alone.

Perhaps the best way to resolve this is to draw up
a table of all the operations for ALL pairs of
types and define the lot.

Then show which definitions are not required because they
will be handled by promotions/conversions. Then we must
check that nothing strange can happen.

Anyone?

John (MAX) Skaller

unread,
Jun 29, 1992, 12:19:22 PM6/29/92
to
In article <1992Jun29....@lth.se> d...@control.lth.se (Dag Bruck) writes:
>
>Do you think exceptions should be used for reporting an error?
>If so, why? If not so, why?

My guess is that the answer to this question is "the same as for
division".

Has there been any thought on NaNs? (Not A Number?)
I often want division by zero NOT to generate an error,
I want to calculate some complicated formula, and check the
answer afterwards, in fact, I might want to print " NaN "
on the screen ... so I don't want the flow of control
interrupted at all.

Can exceptions be configured to do this? Mm..

try { x=complicated(a,b,d); printf("%g",x); }
catch ZERODIVIDE { printf(" NaN "); }

[excuse syntax errors here, I've not used exceptions, they're
not *standard* yet :-)

Fernando Pereira

unread,
Jun 27, 1992, 11:24:46 AM6/27/92
to
>In article <1992Jun26.1...@ucc.su.OZ.AU> max...@extro.ucc.su.OZ.AU (John (MAX) Skaller) writes:
>
>> This is an *informal* proposal for an extension to C++.
>>

[deleted]

>A small addendum: if n is an integer, then a ! n should not mean the
>same as pow(a,n). This is for two reasons:
> (1) It is possible to compute a ! n much more efficiently if
> n is an integer than if it is a floating-point number.
> (This is one of the main reasons why an exponentiation
> operator is such a good idea.)

I think you meant if n is an integer >= 0 ...
Although I agree with the idea of using a!b as a pow(a,b) operator.
--
*********************************************************************
* Fernando J. G. Pereira IST/INESC *
* Lisboa - Portugal f...@minerva.inesc.pt *
*********************************************************************

Hans Olsson

unread,
Jun 29, 1992, 2:01:24 PM6/29/92
to
>Well, it really isn't the same mathematically. Again: the issue is
>what happens when the first argument is negative.
>
>Squaring a negative number is a well-defined mathematical operation,
>and computer languages ought to permit it. I would be very disturbed
>if I got a run-time error from trying to compute (-3.)!2. By
>contrast, raising a negative number to a non-integral power is very
>different, and the only correct thing to do with, for example,
>(-1.)^(0.5), is to signal an error.
>

But I thought that operator!(a,b) should equal pow(a,b) and
pow(-3.0,2.0) is 9.0 in C (read K&R II or test it).

Having said that I think there are two problems here and it would be
easier if they were treated separately:
1: How(and if) the pow-function should be overloaded.
2: A simpler notation for the pow-function.(An operator! or operator~ or...)

1:

In my opinion it would be good to have double pow(double,int) in math.h
because:
o The reason we don't have it is C's lack of overloading.
o A simple implementation takes 20 seconds to write.
o It will increase performance and precision on most computers.
o No existing code would break (Am I right on this one?).

I don't know if it would be useful to have double pow(double,unsigned int).

However int pow(int,unsigned) should not be added because existing code
might break and the functions in math.h all deal with real numbers.

2:
I see no reason to add a special operator for the pow-function,
but if it's defined it should be defined exactly as pow.

>Mathematically, then, x!y and x!n are not the same, and they should
>not be treated the same by a computer language. Certainly existing
>languages (e.g., Fortran) do not treat them the same, and I believe
>that C++ should conform to existing practice.

Yes, and the reason that C++ doesn't have x!n is that C didn't have an
operator for it and C doesn't allow overloadable functions.
C++ has the possibility of overloading and it should be used.

>One of the main uses of a power operator is raising a number to a
>small integral power. If operator! doesn't allow this, or if it
>allows it only if that number is positive, then it is so badly broken
>that it will be almost useless.

Agreed.

John (MAX) Skaller

unread,
Jun 29, 1992, 12:35:13 PM6/29/92
to
In article <27...@hydra.Helsinki.FI> mnyk...@cs.Helsinki.FI (Matti Nykanen) writes:
>In <MATT.92Ju...@physics2.berkeley.edu> ma...@physics2.berkeley.edu (Matt Austern) writes:
>
>That's why I like the idea of differentiating between the cases..
> BASE POWER RESULT
> double double double
> double int double
> int unsigned int
>but omitting the problematic case (What if the power<0? What if both are?)
> int int int? double? complex? error?
>The compilers already carry out this type of analysis when inferring the
>type and necessary casts in arithmetic expressions. Note however that
>some "counterintuitive" results follow, e.g. 3!2 is promoted to 3.0!2=9.0,
>because the integer constant 2 cannot be "demoted" to (unsigned)2 to
>give 9 as integer.
>
If there too many counterintuitive things it is a good
argument not to include it in the standard.

In the case of 3 ! 2 it would ALSO promote to double,
because '2' is an int, not an unsigned!

What happens with 'long' arguments?

What happens with 'big' int arguments---should they
be promoted to give a double result or an error or just
truncated?

Thinking about this makes 'int' return types VERY
problematical. It might be nice for 3 ! 2 to be an integer,
but how much advantage is it?

I suspect the case of m ! n (m ~ n ??) giving
an integer answer might well be handled easily by
a few tests for very low orders and the rest with a lookup
table.

If n,m > 4, how many of m ! N > 16 bit answer?

Matt Austern

unread,
Jun 29, 1992, 3:49:37 PM6/29/92
to
In article <1992Jun29....@ucc.su.OZ.AU> max...@extro.ucc.su.OZ.AU (John (MAX) Skaller) writes:

> Thinking about this makes 'int' return types VERY
> problematical. It might be nice for 3 ! 2 to be an integer,
> but how much advantage is it?
>

My guess is that there would be very little advantage. I have never
seen Fortran code, for example, which takes i**j and relies on the
answer being an integer. (In fact, as has already been pointed out,
this can be rather counterintuitive, since an overflow would be
likely. It sets up a nasty trap for people who would like to just
automatically convert all calls to pow() into operator expressions.)

My feeling is that operator!(double, int) should be handled separately
because it is an important special case that is frequently used.
operator!(int,int), however, would be sufficiently rare that I don't
see any benefit in including it.

Jonathan Coxhead

unread,
Jun 29, 1992, 6:49:29 PM6/29/92
to

How short memories are ... not long ago (8 Mar 92),
jb...@forney.berkeley.edu (Joe Buck) put together a concrete proposal for a
power operator, with a lot worked out in detail. I'll repost it here, but I
imagine the two camps should get together.

I've changed this around a bit, so there may be errors that are not Joe
Buck's. Apologies if so. This is reposted without permission ... I imagine
Joe Buck is not listening at the moment, or he might have done this himself.
----------------------------------------------------------------------------
Draft Proposal to add an exponentiation operator to C++

Version 2
March 8, 1992
Joseph T. Buck (jb...@ohm.berkeley.edu)

The portion of the grammar described on p. 72 of the ARM is revised as
follows:

exp-expression:
pm-expression
pm-expression @ exp-expression

multiplicative-expression:
exp-expression
multiplicative-expression * exp-expression
multiplicative-expression / exp-expression
multiplicative-expression % exp-expression

The revision introduces a new operator, @, which is right-associative
and binds more tightly than the multiplication/division operators
(*, /, and %), and more loosely than .*, ->*, cast operators, or
unary operators. The grammar change basically sticks a new production
in between pm-expression and multiplicative-expression.

The @ operator returns the result of raising the first operand to the
power represented by the second operand.

The exponentiation operator, @, groups right-to-left. The operands
of @ must have arithmetic type.

The "usual arithmetic conversions" of section 4.5 are used, with the
following exception:

If the first argument is of one of the types long double, double, or
float, and the second argument is of integral type, integral promotion
(ch 4.1) takes place on the second argument, but no change is made to
the first argument.

Commentary: we wish to allow -2.0@i, but not -2.0@x, where i
is of integral type and x is of floating type.

The effect of these rules is to allow the following combinations of
arguments and result types:

NOTE: I know that the language does not permit overloading
on builtin arguments. I am showing the "simulated prototypes"
for the argument combinations that can occur.

Group 1:
long double operator@ (long double, long double);
double operator@ (double, double);
float operator@ (float, float);

Group 2:
long double operator@ (long double, long int);
long double operator@ (long double, unsigned int);
long double operator@ (long double, int);
double operator@ (double, long int);
double operator@ (double, unsigned int);
double operator@ (double, int);
float operator@ (float, long int);
float operator@ (float, unsigned int);
float operator@ (float, int);

Group 3:
long int operator@ (long int, long int);
unsigned int operator@ (unsigned int, unsigned int);
int operator@ (int, int);

For all three groups, the result when both arguments are zero
is undefined.

For group 1 (both arguments of floating type), the result of a negative
second argument is undefined.

For group 2 (floating base raised to integral power), if the first
argument is zero and the second argument is zero or negative, the
result is undefined. Specification of the precision of group 2
operations is outside the scope of this standard.

For group 3 (both arguments of integral type), if the first argument
is negative the result is undefined. Provided that the result
of the operation can be represented in the result type, group 3
operations are guaranteed to be exact.

Commentary: note that neither ANSI C nor ANSI C++ mandate
the use of IEEE floating point; it would be inconsistent
to demand that the @ operator be specified more strictly
than the * operator.

Specification of the precision of group 2 and group 3 operations are
outside the scope of this standard.

Commentary: I expect such issues to be handled in extensions to
standards such as the IEEE floating point standard to cover
exponentiation and the transcendental functions; just as an
ANSI C compiler need not implement IEEE floating point, an
ANSI C++ compiler need not implement these rules for
exponentiation and the transcendentals.

The effect of an overflow is implementation-dependent.

Commentary: "undefined" means that an arithmetic exception
may occur, or that the result may be garbage, for example,
0@0 might return 1, 0, or an error. I've been asked to
define 0@0 to be 1, but I can't in good conscience mandate
something that isn't correct.

I'm choosing "undefined", rather than specifying exceptions,
to be consistent with how the ARM deals with things like
division by zero.

-------------------------------------------------------------------

"class complex" is not part of the standard at this point. Should
it be standardized, the following operator overloads might be used:

complex operator@ (complex b, complex e) {
return exp (e*log (b));
}

Note, however, that log (complex) is multi-valued, and that just
using the principal value might not suffice in some applications
(e.g. approximation to contour integrals on the complex plane).

// optional: might be desirable because log (double) is cheaper
// and uniquely defined:

complex operator@ (double b, complex e) {
return exp (e*log (b));
}

Alternatively, complex arguments might be passed as "const complex&".

-------------------------------------------------------------------

Now for the objections and questions:

1. But -1@0.5 is complex (0, 1). Why shouldn't that result be returned?

It is inconsistent with the language for the type of the result to
depend on the value of the arguments. If a user wants to deal with
complex results, it's not difficult to specify complex classes. Every
other operator in the language restricts the result to be no more
general than the type of its arguments; e.g. 3/2 = 1, not 1.5, even
though 1.5 is "correct".

2. But nevertheless, complex (0, 1) is the right answer. Users won't
accept this.

Experience with Fortran suggests otherwise. The semantics I've chosen
generally agree with Fortran, and yet everything fits nicely with C++
conventions.

3. You're trying to make my favorite language more like Fortran, and
Fortran is an inferior language.

You're not going to get a lot of the people who use Fortran to convert to
C++ as long as you make life difficult for them. It's not just a matter
of syntax; most compilers are simply going to generate worse code if there
isn't an exponentiation operator, unless the users write their code more
carefully than we can expect. Fortran is inferior in many ways, but there
is a reason why it's still used for large scientific problems, and the
exponentiation operator is one of the reasons (vectorizability is another,
but that's another argument).

4. Why don't you just use the "usual arithmetic conversions" (chapter
4.5 of the ARM)? Why the exception?

Because users will be unhappy if X@2 returns an exception for negative
X, when it's perfectly well-defined.

5. Why isn't it enough to use "pow", especially since you can overload it
to define pow (double, double), pow (double, int), and pow (int, int)?

Most scientific codes contain large amounts of exponentiation; raising a
real exponent to an integer power where the integer is known at compile time
is common, but real or integer unknown exponents are also common. Evaluation
of polynomials (where x@1, x@2, ... are used in sequence) is a common
operation. Forcing the use of pow (...) has several harmful effects:

The code size increases and complicated expressions become more
difficult to read. C/C++ programmers who don't think this is
a problem haven't seen scientific codes, where even with the
exponentiation operator, expressions can require several lines
to write.

Strength reduction becomes much more difficult to apply, unless
pow (...) is made a special function known by the compiler.

Optimizations commonly applied in Fortran compilers when the same
base appears with several constant exponents are also more
difficult.

Scientific users are put off by the lack of a feature they find
very useful. From a posting by Robert Davies:

"Some people have strong feelings about the need for an exponentiation
operator. I quote from Press, Flannery, Tuekolsky and Vetterling in their
respected book "Numerical Recipes in C", pp 14 and 23 "... the slowness of
C's penetration into scientific computing has been due to deficiencies in
the language that computer scientists have been (we think, stubbornly) slow
to recognize. Examples are the lack of a good way to raise a number to small
integer powers ...", "The omission of this operator from C is perhaps the
language's most galling insult to the scientific programmer"."

6. Why not use ** as in Fortran?

It would break "int main (int argc, char **argv)". We can't make ** a
token. As for tricks to make ** do exponentiation for user-defined
classes, I have seen tricky code that overloads both unary * and
binary * to make ** look like an exponentiation operator for a class,
but I'm not impressed with the hackery. Such tricks tend to fail when
more complicated expressions are considered.

7. How about ^, ^^, #, or ~ ?

^ is taken (exclusive-or). It has the wrong precedence and associativity
to be used as an overloaded operator signifying exponentiation.

I could live with ^^, but there is a relation between & and && and |
and || that might suggest a completely different meaning for ^^ to some
(a logical rather than a bitwise exclusive-or).

# doesn't suggest the right thing to me; also it might confuse the
preprocessor if it appeared as the first nonblank character on a line.

~ is currently a unary operator but not a binary operator, and it
would be possible to use it for exponentiation instead; at least
I don't see any conflicts. I prefer @, but this may be a matter of
personal taste. Using ~ instead of @ would be acceptable.

8. @ already has a meaning in gdb. This means we can't use it.

The Gnu project is busy adding more languages; as they are added, gdb
will also grow to parse all of those languages. There will inevitably
be conflicts between language features and gdb features, and in all
such conflicts, debuggers should give way before languages. It
won't be difficult to add a quoting mechanism for distinguishing
language-specific expressions from debugger expressions. If ~ is
chosen instead of @, it should be for a better reason than not
breaking gdb.

9. It will be hard to implement.

I disagree. The modification to the grammar is simple. The single
exception to the "usual arithmetic conversions" rule is not difficult
to check for. A quick and dirty implementation can simply insert
function calls for the various templates shown above, and their number
can be reduced in many environments; strength reduction for common
cases (exponent is a small constant integer) is very easy to apply.
Compared to, say, implementing exceptions, the work required for this
change will be trivial.

10. Andy Koenig's example and questions: is x@3 guaranteed to be
equal to x@3.0? To x*x*x?

The short answer to Andy's question is "no".

Such questions are beyond the scope of the C++ standard. After all,
the C++ standard does not answer the question: is x*2 guaranteed to
be equal to x+x. The IEEE standard for floating point arithmetic
DOES answer the question, but C++ implementations are not required to
implement IEEE floating point (DEC and Cray would be very upset if
this changed).

Implementers would do well to learn from the experience of Fortran
implementers, who have 30 years of experience in dealing with this
problem.

11. But for implementations like cfront, which produce C, the lack of
an exponentiation operator in C is a problem.

Just as overloaded operators for classes are turned into function calls
unless they are inlined, a cfront-like implementation could inline
some cases (turning x@2 into x*x, say) and generate function calls
for the rest. cfront already generates function calls for user-defined
operators; @ could be treated the same way even when used on builtin
types.

12. What is the effect on existing programs?

None. "@" is not used in the current grammar; no existing program
will break.

13. We shouldn't have an exponentiation operator because exponentiation
isn't "close to the machine".

This argument is perhaps better suited for C than for C++. Just the same,
this argument isn't as clear-cut as it might appear. Many machines lack
an integer division instruction; on some DSP chips, it can cost about the
same to evaluate i@j as i/j for integers i and j (where their values are
not known until runtime), and cost substantially less when j is known at
compile time, because division can be 30 times more expensive than
multiplication. Would a language implementer consider not including
division because, on most RISC machines, division is not close to the
machine?

14. "@" isn't on all keyboards; this is the trigraph problem all over
again.

Someone has commented by email "I believe that @ is specific to US ASCII". I
don't know that it is. Let's suppose that this is true. If this were the
first such case, it would be a strong objection. But since there are
already about nine other cases, this one can be solved in similar ways
(trigraph, special keyword). If that isn't acceptable, I suppose that
binary ~ could be used instead, but ~ is not on all keyboards either.

15. Are there any other benefits or impact?

Many have argued that the most important reason for adding the
exponentiation operator is not so that it can be used on builtin types,
but rather so that it can be used on user-defined types.

The new operator might also be used for overloading in situations where
the intuitive meaning "at" is a useful mnemonic, just as << and >> are
used with streams.

If we attract more Fortran users they might ask us to implement
EQUIVALENCE next. :-)
--
Joe Buck jb...@ohm.berkeley.edu

/|
(_|/
/|
(_/

David Gottner

unread,
Jun 29, 1992, 4:29:35 PM6/29/92
to
I like the idea. However, the '!' operator should return an integer if the two
arguments are integers as well. Thus you could use the '!' operator to create
bitmasks:

mask = 2!x - 1;

(Yes you could also use
mask = (1<<x) - 1;
but the exponentiation might be clearer to some programmers)
--
Amrit Prem | Bring your compass
dav...@auto-trol.com | Lest you get lost at C
{...}ncar!ico!auto-trol!younam |

Joe Buck

unread,
Jun 29, 1992, 9:50:46 PM6/29/92
to
In article <16...@acorn.co.uk> jcox...@acorn.co.uk (Jonathan Coxhead) writes:
>
> How short memories are ... not long ago (8 Mar 92),
>jb...@forney.berkeley.edu (Joe Buck) put together a concrete proposal for a
>power operator, with a lot worked out in detail. I'll repost it here, but I
>imagine the two camps should get together.
>
> I've changed this around a bit, so there may be errors that are not Joe
>Buck's. Apologies if so. This is reposted without permission ... I imagine
>Joe Buck is not listening at the moment, or he might have done this
himself.

It's not that I'm not listening; what happened is that, based on the
experience of Jim Adcock and others, formal proposals get nowhere without
a champion who is an active committee member. I sought a volunteer who is
on the committee to champion this one, and none stepped forward.

The proposal you copy uses "@"; "~" would work as well. "!" is a bad
choice because the corresponding assignment operator would be "!=".

I thought I did a third draft to fix some problems in the second one,
but I don't see it around.

--
Joe Buck jb...@ohm.berkeley.edu

Jim Adcock

unread,
Jun 29, 1992, 9:38:50 PM6/29/92
to
In article <1992Jun29....@ucc.su.OZ.AU> max...@extro.ucc.su.OZ.AU (John (MAX) Skaller) writes:
| If there too many counterintuitive things it is a good
|argument not to include it in the standard.

But this argument leaves ANSI-C++ identical to ANSI-C ;-)

Alan Braggins

unread,
Jun 30, 1992, 7:07:14 AM6/30/92
to
>>>>> On 29 Jun 92 20:29:35 GMT, dav...@auto-trol.com (David Gottner) said:

> I like the idea. However, the '!' operator should return an integer if the two
> arguments are integers as well. Thus you could use the '!' operator to create
> bitmasks:

> mask = 2!x - 1;

> (Yes you could also use
> mask = (1<<x) - 1;
> but the exponentiation might be clearer to some programmers)

Why? The shift is an established idiom, and more general
e.g. mask = (3<<x) for a couple of bits

It also seems to me that the result of exponentiation is naturally
regarded as a number, whereas shift acts on bit patterns.

If (int!int) returns int, it should be for precision. Since it is
not possible to have both
double operator!(int, int) and int operator!(int, int)
I believe the desire to avoid overflow makes double operator!(int, int)
more desirable.
Possibly a compiler could recognize ((int)(n!m)) and do something
faster/more accurate? (Maybe only for small constant values of n,m).
--
Alan Braggins, Shape Data (A Division of EDS Ltd), Cambridge, UK +44-223-316673
"Any technology distinguishable from magic is insufficiently advanced."
"My employer does not necessarily share my views - but I'm working on it."

John (MAX) Skaller

unread,
Jun 30, 1992, 9:05:02 AM6/30/92
to
In article <1992Jun29.1...@lth.se> f8...@efd.lth.se (Hans Olsson) writes:
>In article <MATT.92Ju...@physics2.berkeley.edu> ma...@physics.berkeley.edu writes:
>>Well, it really isn't the same mathematically. Again: the issue is
>>what happens when the first argument is negative.
>>
>>Squaring a negative number is a well-defined mathematical operation,
>>and computer languages ought to permit it. I would be very disturbed
>>if I got a run-time error from trying to compute (-3.)!2. By
>>contrast, raising a negative number to a non-integral power is very
>>different, and the only correct thing to do with, for example,
>>(-1.)^(0.5), is to signal an error.
>>
>
>But I thought that operator!(a,b) should equal pow(a,b) and
>pow(-3.0,2.0) is 9.0 in C (read K&R II or test it).

The problem is that pow(-3.0,2.0) is complex, it just *happens*
to have a zero imaginary part. What about pow(-3.0, 2*(1.0/3*3)?
Are you sure 1.0/3*3 is *exactly* 1?

In constructive mathematics it is not possible to compare
real numbers for equality. Really, the equality operator should
not be allowed for float or double, it doesn't make sense to test
if 1.0==1.0/3.0*3.0 exactly.

So whether pow(-3.0,2.0) actually gave 9.0 as an answer
or an error would depend on the implementation. That is NOT
true for pow(-3.0,2) since the type of the second argument is an integer
and thus the answer must be real---for sure, no numerical problems
of 1.0/3.0*3.0 being 0.99999999999999 which is NOT exactly 1.

There IS a difference IMHO between pow and operator!, the
former is a library function and NOT part of the language definition,
you can always replace a library function. That is not always
the case with an operator.

We could *insist* that it is the case, enabling user control
of the operator (it is just a smart macro, we insist a!b => pow(a,b),
and the compiler does NOT optimise). Or we can just leave it
up to the vendor. But then we need a proper spec.


>
>Having said that I think there are two problems here and it would be
>easier if they were treated separately:
>1: How(and if) the pow-function should be overloaded.

I think we can already overload pow. Just write pow(double,int).
(It is a C++ function, and pow(double,double) is a C function, but that
should be OK I think).

>2: A simpler notation for the pow-function.(An operator! or operator~ or...)
>

It is not just notation if the compiler recognizes it and
the vendor is free to implement it---and take control away from the user.
Remember non-class operators cannot be overloaded.

>1:
>
>In my opinion it would be good to have double pow(double,int) in math.h
>because:

Perhaps pow(double,long) is safer?

>o The reason we don't have it is C's lack of overloading.
>o A simple implementation takes 20 seconds to write.
>o It will increase performance and precision on most computers.

That depends. I think 486 FPU might do pow(double,double)
faster than any other method, depends on the the algorithm they use.
[It is microcoded anyhow]

But again, having pow(double,int) defined doesn't REQUIRE a different
method, it ALLOWS for it: what it requires is that the answer BE CALCULATED
without error.

>o No existing code would break (Am I right on this one?).

Actually, some broken code might suddenly work!

>
>I don't know if it would be useful to have double pow(double,unsigned int).

I don't think so.

But long pow(long,unsigned long) is another issue.

>
>However int pow(int,unsigned) should not be added because existing code
>might break and the functions in math.h all deal with real numbers.
>
>2:
>I see no reason to add a special operator for the pow-function,
>but if it's defined it should be defined exactly as pow.
>
>>Mathematically, then, x!y and x!n are not the same, and they should
>>not be treated the same by a computer language. Certainly existing
>>languages (e.g., Fortran) do not treat them the same, and I believe
>>that C++ should conform to existing practice.
>
>Yes, and the reason that C++ doesn't have x!n is that C didn't have an
>operator for it and C doesn't allow overloadable functions.
>C++ has the possibility of overloading and it should be used.
>
>>One of the main uses of a power operator is raising a number to a
>>small integral power. If operator! doesn't allow this, or if it
>>allows it only if that number is positive, then it is so badly broken
>>that it will be almost useless.
>
>Agreed.

John (MAX) Skaller

unread,
Jun 30, 1992, 9:15:24 AM6/30/92
to
In article <1992Jun29.2...@auto-trol.com> dav...@auto-trol.com (David Gottner) writes:
>I like the idea. However, the '!' operator should return an integer if the two
>arguments are integers as well. Thus you could use the '!' operator to create
>bitmasks:
>
>mask = 2!x - 1;
>
>(Yes you could also use
> mask = (1<<x) - 1;
>but the exponentiation might be clearer to some programmers)

Perhaps 2!n should be a special case :-)

Your example certainly looks nice, it conforms to the
literature better, but would it ever be useful if the base
were other than 2?

What would happen if there was overflow? or underflow?

The problem I suspect is that 2.0 ! x is radically
different to 2 ! x. (And depends on the type of x too )

The original suggestion was for ! for *numerical*
purposes, using it for bit manipulation is acceptable if, and
only if, it is quite clear that 7!9 is meant to be a silly
but manipulation and not give a double result.

It is bad enough that a!9 works and a!9.0 might give
an error (depending on whether a<0 gives a domain error,
or if the system has a go at it, whether the result is
precise enough to be *sure* the answer is real: perhaps
a!9.000001 would also give a real answer when there should
have been an error)

>--
>Amrit Prem | Bring your compass
>dav...@auto-trol.com | Lest you get lost at C
>{...}ncar!ico!auto-trol!younam |

John (MAX) Skaller

unread,
Jun 30, 1992, 9:26:21 AM6/30/92
to
Or perhaps it leaves us without a language at all :-(

I think that getting a power operator past the committee will
be VERY HARD. Power is difficult because the domain on which
it is well defined (to give a real result) is not pretty, it does
not correspond to any types of C.

I did say *too* counterintuitive: that has a specific meaning,
namely, if the complications are so great that just using 'pow'
does not look so bad comparatively.

It is of course not an argument of substance, the problem
is simple: we must get the definition RIGHT, and unequivocably RIGHT.
The arguments for the form chosen must be rock solid AND it must
be demonstrably more useful than just using pow.

All this goes to show that something as apparently simple
as making "pow" an operator is not actually so simple.

Does anyone know the exact rules FORTRAN uses?

David Gottner

unread,
Jun 30, 1992, 3:14:04 PM6/30/92
to
>>arguments are integers as well. Thus you could use the '!' operator to create
>>bitmasks:
>>
>>mask = 2!x - 1;
>>
>>(Yes you could also use
>> mask = (1<<x) - 1;
>>but the exponentiation might be clearer to some programmers)
>
> Perhaps 2!n should be a special case :-)
>
> Your example certainly looks nice, it conforms to the
>literature better, but would it ever be useful if the base
>were other than 2?

I brought this up because a long time ago I used FORTRAN to write screen
drivers, and the only way to do bitmasks was to create masks using 2**X - 1.
I'm not sure what the FORTRAN rules are, but they allow for integer**integer ->
integer.

(I was amazed, the compiler I used was actually smart enough to generate
a left shift instruction for this case)

--
Amrit Prem |
dav...@auto-trol.com | This area is intentionally left blank
{...}ncar!ico!auto-trol!younam |

Hans Olsson

unread,
Jul 1, 1992, 5:15:09 AM7/1/92
to
In article <1992Jun30....@ucc.su.OZ.AU> max...@extro.ucc.su.OZ.AU (John (MAX) Skaller) writes:
>In article <1992Jun29.1...@lth.se> f8...@efd.lth.se (Hans Olsson) writes:
[Deleted old article]

>>
>>But I thought that operator!(a,b) should equal pow(a,b) and
>>pow(-3.0,2.0) is 9.0 in C (read K&R II or test it).
>
> The problem is that pow(-3.0,2.0) is complex, it just *happens*
>to have a zero imaginary part. What about pow(-3.0, 2*(1.0/3*3)?
>Are you sure 1.0/3*3 is *exactly* 1?
>

But seriously, do you actually square numbers by raising them to
2*(1.0/3*3) ?

> In constructive mathematics it is not possible to compare
>real numbers for equality. Really, the equality operator should
>not be allowed for float or double, it doesn't make sense to test
>if 1.0==1.0/3.0*3.0 exactly.
>
> So whether pow(-3.0,2.0) actually gave 9.0 as an answer
>or an error would depend on the implementation. That is NOT
>true for pow(-3.0,2) since the type of the second argument is an integer
>and thus the answer must be real---for sure, no numerical problems
>of 1.0/3.0*3.0 being 0.99999999999999 which is NOT exactly 1.

But pow is not overloaded right now so the type of the second argument is
double.

From K&R II,(because I don't have the ANSI-C standard (hopefully the ANSI-C
standard gives a correct definition of when a double is an integer)):

.... x and y are of type double ....
pow(x,y) A domain error occurs if x=0 and y<=0, or if x<0 and y is not an
INTEGER.
^^^^^^^


>
> There IS a difference IMHO between pow and operator!, the
>former is a library function and NOT part of the language definition,
>you can always replace a library function. That is not always
>the case with an operator.

The C++ standard must after all standarize <new.h> so why not make
small changes to <math.h> ?

Or they could say that <math.h> might contain overloaded versions
of the functions it contains, but without requiring them.
(float sin(float),long double sin(long double)...)

If the C++ standard is going to leave the the contents of <math.h> undefined
there's nothing that would prevent an implementation from adding
double pow(double,int) today.

>
> We could *insist* that it is the case, enabling user control
>of the operator (it is just a smart macro, we insist a!b => pow(a,b),
>and the compiler does NOT optimise). Or we can just leave it
>up to the vendor. But then we need a proper spec.
>>
>>Having said that I think there are two problems here and it would be
>>easier if they were treated separately:
>>1: How(and if) the pow-function should be overloaded.
>
> I think we can already overload pow. Just write pow(double,int).
>(It is a C++ function, and pow(double,double) is a C function, but that
>should be OK I think).

Correct, Bjarne does this in The C++ Programming Language, but I was
talking about the functions in <math.h> and not user-defined ones.

>
>>2: A simpler notation for the pow-function.(An operator! or operator~ or...)
>>
>
> It is not just notation if the compiler recognizes it and
>the vendor is free to implement it---and take control away from the user.
>Remember non-class operators cannot be overloaded.

Correct: It's a simpler notation and giving up the ability to replace
the function with a correct one (some implementors actually have problems
with getting one pow-function right).

>
>>1:
>>
>>In my opinion it would be good to have double pow(double,int) in math.h
>>because:
>
> Perhaps pow(double,long) is safer?
>
>>o The reason we don't have it is C's lack of overloading.
>>o A simple implementation takes 20 seconds to write.
>>o It will increase performance and precision on most computers.
>
> That depends. I think 486 FPU might do pow(double,double)
>faster than any other method, depends on the the algorithm they use.
>[It is microcoded anyhow]

I find it hard to believe that pow(x,(double)2) is faster than x*x.

>
>But again, having pow(double,int) defined doesn't REQUIRE a different
>method, it ALLOWS for it: what it requires is that the answer BE CALCULATED
>without error.

But the point I was trying to make is that it's already required.
It might however be easier to write a pow(double,int) because
you know that integers are integers, so you can safely omit the test.

[Deleted text]
[BTW operator@ is already in The C++ Programming Language :-) ]

Peter Hamer

unread,
Jul 1, 1992, 7:50:09 AM7/1/92
to
In the referenced article max...@extro.ucc.su.OZ.AU (John (MAX) Skaller) writes:
>In article <MATT.92Ju...@physics2.berkeley.edu> ma...@physics.berkeley.edu writes:
>>In article <1992Jun28....@ucc.su.OZ.AU> max...@extro.ucc.su.OZ.AU (John (MAX) Skaller) writes:
>>
>>> >I agree that operator!(double, double) and operator!(double, int) should
>>> >have different semantics.
>
>Perhaps the best way to resolve this is to draw up
>a table of all the operations for ALL pairs of
>types and define the lot.

1) I strongly agree that C++ should permit expressions to use an infix
exponential operator. Not having such a facility will certainly discourage
potential users of C++ in the numerical community.

2) The discussion following on from the initial proposal clearly indicates the
complexities it can lead to. And we haven't even started to consider user-
defined types yet!

3) I would like to remake a proposal I made some time ago. [using ~ for
illustration, the choice od symbol is of secondary concern]

a) Compilers will interpret a~b exactly as if it was exponentiation(a,b).

b) The [heavily overloaded] exponentiation routine(s) are NOT part of the
C++ language. (Although a minimal set might be provided with a compiler,
this should have no standards implications.)

c) Interested parties [eg numerical people] provide exponentiation routines
for the inbuilt types. Perhaps several libraries for different branches
of numerical work.

d) Other interested parties [eg providers of classes such as matrix, bignum,
rational] provide exponentiation routines for their classes.

e) Ultimately the programmer can supply exponentiation routines for their
own classes, or any cases they cannot find code for.

4) I think that this cuts the Gordian knot.

a) It enables the numeric community to write programs in the `natural'
notation.

b) It allows for exponentiation of/by user-defined classes.

c) The C++ standards committee do not need to define 1001 cases such as
(signed int)~(unsigned int)->(signed int). They are not the right group
anyway.

d) It lets the numerical people sort out `their' problems themselves. For
different types of numerical work, different criteria are appropriate
for exponentiation (eg speed, range, accuracy). It is wildly improbable
that a single definition is going to satisfy everybody. This proposal
lets the user make this choice (hopefully by picking alternatives from a
library).

e) The compiler people have to handle a special syntactic case. Presumably
not too difficult.


Regards, Peter

Alan Braggins

unread,
Jul 2, 1992, 6:46:25 AM7/2/92
to
>>>>> On 1 Jul 92 11:50:09 GMT, p...@bnr.co.uk (Peter Hamer) said:

> 3) I would like to remake a proposal I made some time ago. [using ~ for
> illustration, the choice od symbol is of secondary concern]

> a) Compilers will interpret a~b exactly as if it was exponentiation(a,b).

> b) The [heavily overloaded] exponentiation routine(s) are NOT part of the
> C++ language. (Although a minimal set might be provided with a compiler,
> this should have no standards implications.)

This leaves ~ (or whatever) as the only operator which is overloadable on
builtin types. Do we want this?
Or is (a + b) the same as plus(a,b) where a full set of addition routines
must be provided?

Dag Bruck

unread,
Jul 2, 1992, 8:10:34 AM7/2/92
to
In <comp.lang.c++,comp.std.c++> max...@extro.ucc.su.OZ.AU (John (MAX) Skaller) writes:

>In article <...> d...@control.lth.se (Dag Bruck) writes:
>>
>>Do you think exceptions should be used for reporting an error?
>>If so, why? If not so, why?
>
>My guess is that the answer to this question is "the same as for
>division".

People have suggested that operator!(double, double) should be
regarded as a synonym for the standard C function pow(double, double).
If, so the only reasonable error handling approach is for operator! to
report/handle/etc errors exactly the same way as pow(). Agree?

The problem is that exceptions are a much better mechanism for
handling errors than just setting "errno" and returning a garbage
value.

The trade-off is C compatibility vs. language power, which is quite
interesting because operator! is a "pure" extension to C and C++.

I agree that an exponentiation operator would be a syntactic
convenience. Are there any other reasons why we need this operator?
If you can show that you can do something in a significantly better way
with an operator instead of a function, that would be strong argument
in favour of operator!. What it all boils down to, is that before you
try to work out the nitty-gritty details of the proposal, you must
have a good motivation.


-- Dag

John (MAX) Skaller

unread,
Jul 2, 1992, 2:13:14 PM7/2/92
to
In article <ALANB.92J...@walrus.sdl.mdcbbs.com> al...@sdl.mdcbbs.com (Alan Braggins) writes:
>>>>>> On 1 Jul 92 11:50:09 GMT, p...@bnr.co.uk (Peter Hamer) said:
>
>> 3) I would like to remake a proposal I made some time ago. [using ~ for
>> illustration, the choice od symbol is of secondary concern]
>
>> a) Compilers will interpret a~b exactly as if it was exponentiation(a,b).
>
>> b) The [heavily overloaded] exponentiation routine(s) are NOT part of the
>> C++ language. (Although a minimal set might be provided with a compiler,
>> this should have no standards implications.)
>
>This leaves ~ (or whatever) as the only operator which is overloadable on
>builtin types. Do we want this?
>Or is (a + b) the same as plus(a,b) where a full set of addition routines
>must be provided?

1) If we do this, it would not *actually* map to "exponentiation".

You would define operator~ as for any other overloadable operator.

2) Three choices seem available:

A) Use 'pow'. Status quo.

B) Define operator~ as proper power operator.

C) Give operator! the right syntax and allow the user to
overload it, even for built in types. Compilers could
provide 'default' interpretations.

The problem with (A) is that pow(a,b) is ugly and potentially
inefficient. The advantage is that .. it is the status quo.

The problem with (B) is that there must be a clear agreed upon
definition, and we must trust compiler implementer to provide
suitably accurate and fast operations.

The problem with (C) is that everyone will have different definitions.
It is not just a problem of speed and accuracy, but syntax, that is
whether, for example, double~int is promoted to double~double or not
makes a big difference, especially if your version of double~double
gives a domain error for negative first argument (even if the second
happens to be integral) and someone elses doesn't.

[You can't fix this by porting your ~ operators with the code
because they are written in assmebler !! Perhaps porting
the declarationw would suffice. BUT then how do you
use TWO peoples differnt ~ methods together??]

Overloading ~ for non-class types is not a problem, the restriction
is there only to prevent changing the meaning of existing C definitions
for these operators, and that doesn't include ~.

Which version do you support, and why?

For (B) refer to Joe Bucks proposal for operator@.
[@ is not acceptable I think, but that is trivia at the moment.]

John (MAX) Skaller

unread,
Jul 2, 1992, 2:40:04 PM7/2/92
to
In article <1992Jul2....@lth.se> d...@control.lth.se (Dag Bruck) writes:
>In <comp.lang.c++,comp.std.c++> max...@extro.ucc.su.OZ.AU (John (MAX) Skaller) writes:
>>In article <...> d...@control.lth.se (Dag Bruck) writes:
>>>
>>>Do you think exceptions should be used for reporting an error?
>>>If so, why? If not so, why?
>>
>>My guess is that the answer to this question is "the same as for
>>division".
>
>People have suggested that operator!(double, double) should be
>regarded as a synonym for the standard C function pow(double, double).
>If, so the only reasonable error handling approach is for operator! to
>report/handle/etc errors exactly the same way as pow(). Agree?
>
>The problem is that exceptions are a much better mechanism for
>handling errors than just setting "errno" and returning a garbage
>value.

In fact, use of NaNs is even more desirable in many
numerical situations.

>
>The trade-off is C compatibility vs. language power, which is quite
>interesting because operator! is a "pure" extension to C and C++.

Is there a tradeoff? There is no suggestion to *remove*
the C 'pow' function from the library!


>
>I agree that an exponentiation operator would be a syntactic
>convenience. Are there any other reasons why we need this operator?
>If you can show that you can do something in a significantly better way
>with an operator instead of a function, that would be strong argument
>in favour of operator!. What it all boils down to, is that before you
>try to work out the nitty-gritty details of the proposal, you must
>have a good motivation.
>
>
> -- Dag

The 'syntactic convenience' is the MAJOR argument. It is not
just a nicety. The arguement is the SAME as for a+b vs. plus(a,b)
[given overloading]. The argument is actually much stronger
for C than C++ because in C you would need 'pow', 'pow_int' etc,
and you might call the wrong one.

There is a MINOR argument that an intrinsic pow operator
might lead to improved optimisation.

Why is readability important? Would you be prepared
to eliminate all infix operators? No? Then the only reason
for forgetting 'pow' is that you aren't a numerical analyst,
or, it is too hard to define.

As has been pointed out, although 'pow' is not so common
[but also % is not so common, is it?] it usually occurs in
complicated numerical expressions.

In such cases program correctness suffers because
visual comparison of the C++ source vs say the FORTRAN source
from which a translation is being done by hand, or a published
algorithm, cannot be easily done.

On the other hand, providing an infix power operator
syntax is trivial, there is NO good argument not to.
[ I mean, giving the operator the right precedence and associativity,
not defining the argument types involved ]

The only
reasonable argument not to provide pow is that a simple, clear
*semantic* has not yet been defined.
[What are the types involved, how to handle errors,
how accurate is the result]

IMHO, that argument
still stands ... we are *not* ready to submit a proposal.
But I think Joe Bucks @ proposal might be quite close.

The other possibility is to allow the operator to be
overloaded by the user. Perhaps you might comment on the desirability of
this idea. I think it might cause major portability problems,
but I just don't know. [It would be a definite departure from C,
there could be no 'retro-fitting' to C]

Matt Austern

unread,
Jul 2, 1992, 8:05:00 PM7/2/92
to
In article <1992Jul2.1...@ucc.su.OZ.AU> max...@extro.ucc.su.OZ.AU (John (MAX) Skaller) writes:

> The other possibility is to allow the operator to be
> overloaded by the user. Perhaps you might comment on the desirability of
> this idea. I think it might cause major portability problems,
> but I just don't know.

If correctly defining the semantics of an exponentiation operator is
difficult, then this problem is not solved by putting the burden of
defining those semantics on the user! (I'm not sure about portability
problems, but it would certainly cause readibility problems.)

Fortunately, I don't think that defining the semantics really is
difficult. There are some open issues, but that isn't because we are
forced with a decision where there is no right choice; it is because
we have decisions where there are a number of reasonable choices.

And, after all, we could do worse than to just define the semantics of
the C++ exponentiation operator to be the same as that of the Fortran
exponentiation operator: there are a great many legitimate complaints
about Fortran, but I have never heard anyone complain that the design
of its exponentiation operator is grossly broken. (And I don't see
any reason why the C++ operator would have to be different at all,
aside from the trivial difference that the token used in Fortran, **,
is unacceptable for C++.)

I've been thinking for a while that it might be useful to post the
language specifications for the exponentiation operator in Fortran,
just to make this discussion slightly more concrete. Does anyone else
think that might be useful?

Matt Welsh

unread,
Jul 3, 1992, 9:09:43 AM7/3/92
to
In article <1992Jul2.1...@ucc.su.OZ.AU> max...@extro.ucc.su.OZ.AU (John (MAX) Skaller) writes:
>
> A) Use 'pow'. Status quo.
>
> B) Define operator~ as proper power operator.
>
> C) Give operator! the right syntax and allow the user to
> overload it, even for built in types. Compilers could
> provide 'default' interpretations.
>
>
>Which version do you support, and why?
>

How about (D) (which I posted my proposal to a little while ago)-- we
allow all operators to be overloaded for inbuilt, non-class types. IMHO, this
would solve the problem annd give the C++ a great deal of power that it's
lacking. I don't know of any real disadvantages to this proposal-- it
wouldn't "break" existing C++ programs or compilers. It's a lot less
crufty than (B) or (C). If not, then I would stick with (A).


>;----------------------------------------------------------------------
> JOHN (MAX) SKALLER, max...@extro.ucc.su.oz.au
> Maxtal Pty Ltd, 6 MacKay St ASHFIELD, NSW 2131, AUSTRALIA
>;--------------- SCIENTIFIC AND ENGINEERING SOFTWARE ------------------


---mdw


Matt Welsh wel...@dg-rtp.dg.com
UNIX-SQA, Data General Corporation RTP Office: (919)248-6070
"You're a jerk, Dent. A complete kneebiter."

Patrick Taylor

unread,
Jul 3, 1992, 8:00:17 PM7/3/92
to
In article <1992Jun27....@inesc.pt> f...@minerva.inesc.pt (Fernando Pereira) writes:
>Xref: exucom.exu.ericsson.se comp.lang.c++:10555 comp.std.c++:720
>Newsgroups: comp.lang.c++,comp.std.c++
>Path: exucom.exu.ericsson.se!ericom!sunic2!mcsun!inesc.inesc.pt!usenet
>From: f...@minerva.inesc.pt (Fernando Pereira)
>Subject: Re: Power operator! for C++
>Message-ID: <1992Jun27....@inesc.pt>
>Sender: use...@inesc.pt (USENET News System)
>Nntp-Posting-Host: minerva.inesc.pt
>Organization: INESC, Lisboa, Portugal
>References: <1992Jun26.1...@ucc.su.OZ.AU> <MATT.92Ju...@physics.berkeley.edu>
>Date: Sat, 27 Jun 1992 15:24:46 GMT

>In article <MATT.92Ju...@physics.berkeley.edu> ma...@physics.berkeley.edu writes:
>>In article <1992Jun26.1...@ucc.su.OZ.AU> max...@extro.ucc.su.OZ.AU (John (MAX) Skaller) writes:
>>
>>> This is an *informal* proposal for an extension to C++.
>>>

>[deleted]

>>A small addendum: if n is an integer, then a ! n should not mean the
>>same as pow(a,n). This is for two reasons:
>> (1) It is possible to compute a ! n much more efficiently if
>> n is an integer than if it is a floating-point number.
>> (This is one of the main reasons why an exponentiation
>> operator is such a good idea.)

> I think you meant if n is an integer >= 0 ...
> Although I agree with the idea of using a!b as a pow(a,b) operator.

Even if it's not. 3 ! (-6) is simply 1 / (3 ! 6), much easier and faster
than using ln() and exp()

>--
>*********************************************************************
>* Fernando J. G. Pereira IST/INESC *
>* Lisboa - Portugal f...@minerva.inesc.pt *
>*********************************************************************

"This must be Thursday. I never could get the hang of Thursdays" - D Adams
- Patrick Taylor
Ericsson Network Systems exu...@exu.ericsson.se "Don't let the .se fool you" alternately, exu...@ZGNews.Lonestar.Org

John (MAX) Skaller

unread,
Jul 4, 1992, 2:46:27 AM7/4/92
to
In article <1992Jul3.1...@dg-rtp.dg.com> wel...@mirage.rtp.dg.com (Matt Welsh) writes:
>
>How about (D) (which I posted my proposal to a little while ago)-- we
>allow all operators to be overloaded for inbuilt, non-class types. IMHO, this
>would solve the problem annd give the C++ a great deal of power that it's
>lacking. I don't know of any real disadvantages to this proposal-- it
>wouldn't "break" existing C++ programs or compilers. It's a lot less
>crufty than (B) or (C). If not, then I would stick with (A).
>

You can't overload + for standard types. It is already
defined for all combinations. Any new definition would have
to be an error (redefinition).

--

Matt Welsh

unread,
Jul 4, 1992, 2:19:10 PM7/4/92
to
>In article <1992Jul3.1...@dg-rtp.dg.com> I write:
>>
>>How about (D) (which I posted my proposal to a little while ago)-- we
>>allow all operators to be overloaded for inbuilt, non-class types. IMHO, this
>>would solve the problem annd give the C++ a great deal of power that it's
>>lacking. I don't know of any real disadvantages to this proposal-- it
>>wouldn't "break" existing C++ programs or compilers. It's a lot less
>>crufty than (B) or (C). If not, then I would stick with (A).
>>
>
> You can't overload + for standard types. It is already
>defined for all combinations. Any new definition would have
>to be an error (redefinition).
>

Then why not allow one to redefine (that's right, *redefine*) what the
operator does? Seems like a possibility to me.


>;----------------------------------------------------------------------
> JOHN (MAX) SKALLER, max...@extro.ucc.su.oz.au
> Maxtal Pty Ltd, 6 MacKay St ASHFIELD, NSW 2131, AUSTRALIA
>;--------------- SCIENTIFIC AND ENGINEERING SOFTWARE ------------------

John (MAX) Skaller

unread,
Jul 5, 1992, 6:58:08 AM7/5/92
to
In article <1992Jul4.1...@dg-rtp.dg.com> wel...@mirage.rtp.dg.com (Matt Welsh) writes:
>>In article <1992Jul3.1...@dg-rtp.dg.com> I write:
>>>
>>>How about (D) (which I posted my proposal to a little while ago)-- we
>>>allow all operators to be overloaded for inbuilt, non-class types. IMHO, this
>>>would solve the problem annd give the C++ a great deal of power that it's
>>>lacking. I don't know of any real disadvantages to this proposal-- it
>>>wouldn't "break" existing C++ programs or compilers. It's a lot less
>>>crufty than (B) or (C). If not, then I would stick with (A).
>>>
>>
>> You can't overload + for standard types. It is already
>>defined for all combinations. Any new definition would have
>>to be an error (redefinition).
>>
>
>Then why not allow one to redefine (that's right, *redefine*) what the
>operator does? Seems like a possibility to me.
>
>
What scope would the redefinitions have? If int+int were
considered extern, then library routines would suddenly use this new
definition. They would now longer function as intended.
Further, int+int could not be inlined, because such inlines
once compiled could not be redefined (you can't get into
an object file and change the code because another module
happened to redefine int+int). If int+int were inlined in a library,
then the definition would NOT be changed there, but it would in
all routines seeing the new definition. It is inconsistent.

This cannot happen with operators on classes---they cannot
be redefined. You can *substitute* a new defintion at link time.
In short: redefintion of standard types consistently over a program
would require them to be implemented as external functions,
precluding optimisation, and allowing the standard operation
of a program to be changed *after it is written*.

Note that this can be done with operator new and delete.

If the redefinition were defined inline in a header file,
it would depend whether that file were included or not what
int+int meant. Nowhere else does the language allow this.
There must be exactly ONE definition of every function actually
used.

What you suggest is equivalent to having two inline
int+int definitions, one used in some modules and the other
in other modules. I do not think this is in the best interests
of maintainable software. Mixing up the desired definitions
would not lead to an error at compile time, only strange run
time behaviour.

I think for this reason an undefined pow operator
is also not a good idea.


--

Fergus James HENDERSON

unread,
Jul 6, 1992, 3:47:43 AM7/6/92
to
max...@extro.ucc.su.OZ.AU (John (MAX) Skaller) writes:

>In article <1992Jul3.1...@dg-rtp.dg.com> wel...@mirage.rtp.dg.com (Matt Welsh) writes:
>>
>>How about (D) (which I posted my proposal to a little while ago)-- we
>>allow all operators to be overloaded for inbuilt, non-class types. IMHO, this
>>would solve the problem annd give the C++ a great deal of power that it's
>>lacking. I don't know of any real disadvantages to this proposal-- it
>>wouldn't "break" existing C++ programs or compilers. It's a lot less
>>crufty than (B) or (C). If not, then I would stick with (A).
>
> You can't overload + for standard types. It is already
>defined for all combinations. Any new definition would have
>to be an error (redefinition).
>

What about (char *) + (char *) ?

Personally I would definitely like to be able to overload this to mean
string concatenation.

--
Fergus Henderson f...@munta.cs.mu.OZ.AU
This .signature VIRUS is a self-referential statement that is true - but
you will only be able to consistently believe it if you copy it to your own
.signature file!

John (MAX) Skaller

unread,
Jul 6, 1992, 9:22:19 AM7/6/92
to
In article <921881...@mulga.cs.mu.OZ.AU> f...@munta.cs.mu.OZ.AU (Fergus James HENDERSON) writes:
>max...@extro.ucc.su.OZ.AU (John (MAX) Skaller) writes:
>
>>In article <1992Jul3.1...@dg-rtp.dg.com> wel...@mirage.rtp.dg.com (Matt Welsh) writes:
>>>
>>>How about (D) (which I posted my proposal to a little while ago)-- we
>>>allow all operators to be overloaded for inbuilt, non-class types. IMHO, this
>>>would solve the problem annd give the C++ a great deal of power that it's
>>>lacking. I don't know of any real disadvantages to this proposal-- it
>>>wouldn't "break" existing C++ programs or compilers. It's a lot less
>>>crufty than (B) or (C). If not, then I would stick with (A).
>>
>> You can't overload + for standard types. It is already
>>defined for all combinations. Any new definition would have
>>to be an error (redefinition).
>>
>
>What about (char *) + (char *) ?
>
>Personally I would definitely like to be able to overload this to mean
>string concatenation.
>
Actually, BorlandC *declares* this (because it is syntactically
equivalent to (char*)-(char*) which might be legal. [See ARM]

But (char*) * (char*) is definitely a syntax error!

I have to retract my hasy statement above about *all combinations*,
clearly I am wrong.

I think the key is that you can't usurp operators for pre-defined
types because that might cause conflicts[duplicate definitions]

For user defined types it can only cause conflicts if the class
names *also* cause a conflict.

Matt Welsh

unread,
Jul 6, 1992, 9:24:16 AM7/6/92
to
In article <1992Jul5.1...@ucc.su.OZ.AU> max...@extro.ucc.su.OZ.AU (John (MAX) Skaller) writes:

>In article <1992Jul4.1...@dg-rtp.dg.com> I write:
>>
>>Then why not allow one to redefine (that's right, *redefine*) what the
>>operator does? Seems like a possibility to me.
>>
>>
> What scope would the redefinitions have? If int+int were
>considered extern, then library routines would suddenly use this new
>definition. They would now longer function as intended.

I agree with this; when pondering the subject this weekend it
dawned upon me that redefining inbuilt operator types would cause
library routines and inline code (such as code in iostream.h) to
break. Not good at all.

If you really want to have a power operator, one way to do it would
be to make a wrapper class for the value and then define ! or ^ or
whatever for that class. And then define = for that class to assign
its value directly to the class's value member, and overload
the other operators to do comparisons and so on on the value
member of this class, in effect making the class synonymous with
its value member. This is annyoying; can't this be done with
a template?

---mdw

John (MAX) Skaller

unread,
Jul 7, 1992, 12:44:00 AM7/7/92
to
In article <1992Jul6.1...@dg-rtp.dg.com> wel...@mirage.rtp.dg.com (Matt Welsh) writes:
>In article <1992Jul5.1...@ucc.su.OZ.AU> max...@extro.ucc.su.OZ.AU (John (MAX) Skaller) writes:
>>In article <1992Jul4.1...@dg-rtp.dg.com> I write:
>>>
>
>If you really want to have a power operator, one way to do it would
>be to make a wrapper class for the value and then define ! or ^ or
>whatever for that class. And then define = for that class to assign
>its value directly to the class's value member, and overload
>the other operators to do comparisons and so on on the value
>member of this class, in effect making the class synonymous with
>its value member. This is annyoying; can't this be done with
>a template?

Something like:

class Double {
public:
operator double(){return v;}
Double(double x) : v(x) {}
private:
double v;
};

Double interconverts with double wherever needed.
But it won't convert/promote to anything else.
All standard numeric types convert to Double though.

It has the advantage that

f(Double);
f(1.2); // works
Float x; // as for Double
f(x); // fails, type mismatch


Now you can write

Double operator^(Double,Double);

and say

Double(1.2)^2;

or

Double d;
d^1.2;

You can use a template to have:

typedef ClassFromStandard<double> Double;

The technique leaves something to be desired, but also has advantages.

Another mod:

class _meters;
class _kilograms;

typedef UnitClass<double,_metres> Metres;
typedef UnitClass<double,_kilograms> Kilograms;

allows some dimensional checking:

f(Metres);
Metres m;
Kilograms k;

f(1.2); // ok
f(m); // ok
f(k); // error

but doesn't really hack it when it comes to metres/second etc.

Bruce...@bbs.actrix.gen.nz

unread,
Jul 14, 1992, 11:39:10 PM7/14/92
to
In article <8...@nazgul.UUCP> bri...@nazgul.UUCP (Walter Bright) writes:
> Zortech C/C++ is the only compiler so far that has stable and robust behavior
> regarding NANs and infinities. All the library functions dealing with floating
> point now have defined behavior with all the different IEEE special cases.
> The compiler itself can handle NANs, such as:
> static double d = NAN;
> It also has hex floating point, all 26 IEEE 754 comparison operators implemented
> and a complete set of NCEG 91-015 floating point extensions.
>
> P.S. I wrote the compiler.

Zortech is great, Walter (on the PC anyway), but what's wrong with
this from MPW C++?

catenate test.cp
#include <iostream.h>

void main(){
cout << "3/0 gives " << 3.0/0.0 << ", 0/0 gives " << 0.0/0.0;
};
buildprogram test >dev:null
test
3/0 gives INF, 0/0 gives NAN(004)

--
Bruce...@bbs.actrix.gen.nz Twisted pair: +64 4 477 2116
BIX: brucehoult Last Resort: PO Box 4145 Wellington, NZ
"Cray's producing a 200 MIPS personal computer with 64MB RAM and a 1 GB
hard disk that fits in your pocket!" "Great! Is it PC compatable?"

Walter Bright

unread,
Jul 20, 1992, 1:49:10 PM7/20/92
to
In article <1992Jul15....@actrix.gen.nz> Bruce...@bbs.actrix.gen.nz writes:
/In article <8...@nazgul.UUCP> bri...@nazgul.UUCP (Walter Bright) writes:
/> Zortech C/C++ is the only compiler so far that has stable and robust behavior
/> regarding NANs and infinities. All the library functions dealing with floating
/> point now have defined behavior with all the different IEEE special cases.
/> The compiler itself can handle NANs, such as:
/> static double d = NAN;
/Zortech is great, Walter (on the PC anyway), but what's wrong with
/this from MPW C++?
/
/#include <iostream.h>
/void main(){
/ cout << "3/0 gives " << 3.0/0.0 << ", 0/0 gives " << 0.0/0.0;
/};
/buildprogram test >dev:null
/test
/3/0 gives INF, 0/0 gives NAN(004)

There is nothing at all wrong with it. It is simply not enough. 0.0/0.0 as
a substitute for NAN has the non-portable deficiency of how the compiler handles
exceptions when constant folding. NCEG defines all these behaviors, and
offers things like isnan(double), and a long list of other things.
Lots of compiler printf's cannot handle NANs, for instance, check out C7's
library reference on what happens if you pass a NAN for a double:
digit.#NANrandom-digits
(I am not kidding...) Some printf's will hang or crash if you pass NAN
or INFINITY.

I'd rather program NAN than 0.0/0.0, and likewise for INFINITY.
All the library functions should be able to handle these special values.

Some of what NCEG does is simply to nail down the behavior instead of leaving
it undefined like ANSI C does.

0 new messages