## digitalmars.D - typing base ^^ exp

• Andrei Alexandrescu (22/22) Feb 14 2010 I've tested the typing rules for ^^ and they seem wanting. One painful
• BCS (4/16) Feb 14 2010 It might if my brain was willing to parse out the @'s :)
• Andrei Alexandrescu (3/19) Feb 14 2010 Word. I'm looking at 460 pages worth of those.
• BCS (4/9) Feb 14 2010 How much do you spend on asprin? :)
• Michel Fortin (25/41) Feb 14 2010 It's much more readable this way:
• Don (19/46) Feb 14 2010 The problem with this rule is (if I understand correctly) that a2 ^^ 2
• Simen kjaeraas (8/20) Feb 15 2010 I believe any and all powExps with integral base and exp should yield an
```I've tested the typing rules for ^^ and they seem wanting. One painful
example:

int a2 = 3, b2 = -2;
writeln(typeof(a2 ^^ b2).stringof);
writeln(a2 ^^ b2);

The program writes:

int
zsh: floating point exception  ./test.d

Ouch. Here's what I suggest:

====
The type of  the power expression is:  uint  if  both  base  and  exp
have unsigned  types less  than  ulong ;  int   if  base  is  a signed
integer  less than   long  and   exp  is  an unsigned  type  less than
ulong ;  ulong  if  both  base  and  exp  have  unsigned types and at
least  one is   ulong ;  long   if  base   is  long   and  exp   is an
unsigned  type; and  double   for all  other combinations  of integral
base  and  exp . If at least one of the operands has a floating point
type,  the result  type is  the largest  participating  floating point
type.
====

Makes sense?

Andrei
```
Feb 14 2010
```Hello Andrei,

The type of  the power expression is:  uint  if  both  base  and  exp
have unsigned  types less  than  ulong ;  int   if  base  is  a signed
integer  less than   long  and   exp  is  an unsigned  type  less than
ulong ;  ulong  if  both  base  and  exp  have  unsigned types and at
least  one is   ulong ;  long   if  base   is  long   and  exp   is an
unsigned  type; and  double   for all  other combinations  of integral
base  and  exp . If at least one of the operands has a floating point
type,  the result  type is  the largest  participating  floating point
type.
====
Makes sense?

It might if my brain was willing to parse out the  's :)

--
<IXOYE><
```
Feb 14 2010
```BCS wrote:
Hello Andrei,

The type of  the power expression is:  uint  if  both  base  and  exp
have unsigned  types less  than  ulong ;  int   if  base  is  a signed
integer  less than   long  and   exp  is  an unsigned  type  less than
ulong ;  ulong  if  both  base  and  exp  have  unsigned types and at
least  one is   ulong ;  long   if  base   is  long   and  exp   is an
unsigned  type; and  double   for all  other combinations  of integral
base  and  exp . If at least one of the operands has a floating point
type,  the result  type is  the largest  participating  floating point
type.
====
Makes sense?

It might if my brain was willing to parse out the  's :)

Word. I'm looking at 460 pages worth of those.

Andrei
```
Feb 14 2010
```Hello Andrei,

BCS wrote:

It might if my brain was willing to parse out the  's :)

Word. I'm looking at 460 pages worth of those.

How much do you spend on asprin? :)

--
<IXOYE><
```
Feb 14 2010    Michel Fortin <michel.fortin michelf.com> writes:
```On 2010-02-14 18:38:18 -0500, BCS <none anon.com> said:

Hello Andrei,

The type of  the power expression is:  uint  if  both  base  and  exp
have unsigned  types less  than  ulong ;  int   if  base  is  a signed
integer  less than   long  and   exp  is  an unsigned  type  less than
ulong ;  ulong  if  both  base  and  exp  have  unsigned types and at
least  one is   ulong ;  long   if  base   is  long   and  exp   is an
unsigned  type; and  double   for all  other combinations  of integral
base  and  exp . If at least one of the operands has a floating point
type,  the result  type is  the largest  participating  floating point
type.
====
Makes sense?

It might if my brain was willing to parse out the  's :)

It's much more readable this way:

===
The type of the power expression is:

* 'uint' if both 'base' and 'exp' have unsigned types less than 'ulong';
* 'int' if 'base' is a signed integer less than 'long' and 'exp' is an
unsigned type less than 'ulong';
* 'ulong' if both 'base' and 'exp' have unsigned types and at
least one is 'ulong';
* 'long' if 'base' is 'long' and 'exp' is an unsigned type; and
* 'double' for all other combinations of integral 'base' and 'exp'.

If at least one of the operands has a floating point type, the result
type is the largest participating floating point type.
===

So "2 ^^ 2" returns a double while "2 ^^ 2u" returns an int... sound
strange, but it makes sense in a way, I'm not sure it's a good idea to
have signed and unsigned operate in such different ways given how many
people tell you to not use unsigned integers unless it's really
necessary. You're obviously worried about things like 3 ^^ -2 here, I'd
be more tempted to define 3 ^^ -2 as 0, same as (1/3)^^2u. But I don't

--
Michel Fortin
michel.fortin michelf.com
http://michelf.com/
```
Feb 14 2010
```Andrei Alexandrescu wrote:
I've tested the typing rules for ^^ and they seem wanting. One painful
example:

int a2 = 3, b2 = -2;
writeln(typeof(a2 ^^ b2).stringof);
writeln(a2 ^^ b2);

The program writes:

int
zsh: floating point exception  ./test.d

Ouch. Here's what I suggest:

====
The type of  the power expression is:  uint  if  both  base  and  exp
have unsigned  types less  than  ulong ;  int   if  base  is  a signed
integer  less than   long  and   exp  is  an unsigned  type  less than
ulong ;  ulong  if  both  base  and  exp  have  unsigned types and at
least  one is   ulong ;  long   if  base   is  long   and  exp   is an
unsigned  type; and  double   for all  other combinations  of integral
base  and  exp . If at least one of the operands has a floating point
type,  the result  type is  the largest  participating  floating point
type.
====

Makes sense?

The problem with this rule is (if I understand correctly) that  a2 ^^ 2
has type of double.
It's crucial that x ^^ 2 has the same type as x. The annoying thing is
that positive literal integers are of type int.

The existing behaviour is intentional (it's an intentionally generated
divide error), although the error should be moved to compile time.
The idea is that int ^^ int should be illegal. Only int ^^ uint should
be valid. The code above would therefore generate a compile-time error
for any circumstance where it is possible for the exponent to be
negative. Range-checking isn't yet fully implemented though. Currently
it only gives an error if the value of y is known at compile-time.

The intended behaviour is:

-1 ^^ exp where exp is an integer is transformed into (exp & 1)? -1 : 1;
1 ^^ exp where exp is an integer is transformed into (exp, 1).
Otherwise, if both base and exp are integral types, and exp cannot be
implicitly converted to an unsigned, a compile time error occurs.

Whenever base ^^ exp is defined, typeof(base ^^ exp) is always the same
as typeof(base * exp).
```
Feb 14 2010    "Simen kjaeraas" <simen.kjaras gmail.com> writes:
```Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote:

====
The type of  the power expression is:  uint  if  both  base  and  exp
have unsigned  types less  than  ulong ;  int   if  base  is  a signed
integer  less than   long  and   exp  is  an unsigned  type  less than
ulong ;  ulong  if  both  base  and  exp  have  unsigned types and at
least  one is   ulong ;  long   if  base   is  long   and  exp   is an
unsigned  type; and  double   for all  other combinations  of integral
base  and  exp . If at least one of the operands has a floating point
type,  the result  type is  the largest  participating  floating point
type.
====

Makes sense?

I believe any and all powExps with integral base and exp should yield an
integral result. If you want a double, you ask for it with a cast.

Especially, as Don pointed out, when positive integral literals in D are
typed as int. "WTF? foo( 2^^2 ) complains about doubles? It don't do
that when I do uint x = 2; foo( 2^^x )!"

--
Simen
```
Feb 15 2010