## digitalmars.D - typing base ^^ exp

- Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> Feb 14 2010
- BCS <none anon.com> Feb 14 2010
- Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> Feb 14 2010
- BCS <none anon.com> Feb 14 2010
- Michel Fortin <michel.fortin michelf.com> Feb 14 2010
- Don <nospam nospam.com> Feb 14 2010
- "Simen kjaeraas" <simen.kjaras gmail.com> Feb 15 2010

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 :)

How much do you spend on asprin? :) -- <IXOYE><

Feb 14 2010

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 have a strong opinion about this. -- 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

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