Hello,

We're starting to look at adding support for unsigned integers to  
X10.  The proposal is to add the following value classes:

Int8, Int16, Int32, Int64 - signed integers of the given widths
Nat8, Nat16, Nat32, Nat64 - unsigned integers of the given widths

More familiar names (e.g., byte, ubyte, short, ushort) will be  
supported via type aliases.

Note that Nat16 is not the same as Char, although they may have the  
same representation.  In particular, toString() should differ, e.g.,  
"97" rather than "a".


So, some questions:

1. How should comparisons between signed and unsigned values work?

Consider:

     u16 = Nat16.MAX; // 2^16-1 == 0xffff;
     u32 = Nat32.MAX; // 2^32-1 == 0xffffffff;
     i32 = -1;        // -1     == 0xffffffff;

What is i32 < u16?

K&R C is "unsignedness preserving":

     i32 < u16 == (nat32) i32 < (nat32) u16 == 0xffffffff < 0xffffffff  
== false

ANSI C is "value preserving":

     i32 < u16 == (int32) -1 < (int32) 0xffff == -1 < 65536 == true

Except if the operands have the same width:

     i32 < u32 == -1 < 2^32-1 == 0xffffffff < 0xffffffff == false

I find both the K&R rule and the ANSI rule are non-intuitive in these  
corner cases.  I think the last test should return true, but it  
doesn't because they have the same representation.

So, here are some of our options:

(a) Be unsignedness preserving in the broken K&R C way.
(b) Be value preserving in the broken ANSI C way.
(c) Be value preserving correctly (i.e., i32 < u32 == true).
(d) Disallow signed vs. unsigned comparisons, forcing the programmer  
to explicitly convert.
(e) Introduce different signed and unsigned operators (probably a bad  
idea)

C#, BTW, does (c) for 32-bit values, but (d) for 64-bit values.

Any opinions?


2. What are the conversion semantics?

Assuming 2's complement representation, we can just truncate or sign  
extend to the right width and reinterpret the bits in the new type.   
When converting from a signed number to a longer unsigned, do we sign  
extend before widening or after?

i16: int16 = -1; // 0xffff
(a) (i16 to nat32) == 0x0000ffff
(b) (i16 to nat32) == 0xffffffff

ANSI C does (b) and I don't see a good reason to be different.


3. Should we get rid of >>> as redundant, since >> on an unsigned int  
would do the same thing?


Thanks,
Nate


-------------------------------------------------------------------------
Check out the new SourceForge.net Marketplace.
It's the best place to buy or sell services for
just about anything Open Source.
http://sourceforge.net/services/buy/index.php
_______________________________________________
X10-users mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/x10-users

Reply via email to