disabling unary "-" for unsigned types
Steven Schveighoffer
schveiguy at yahoo.com
Mon Feb 15 19:40:46 PST 2010
On Mon, 15 Feb 2010 17:21:09 -0500, Walter Bright
<newshound1 at digitalmars.com> wrote:
> Steven Schveighoffer wrote:
>> are there any good cases besides this that Walter has? And even if
>> there are, we are not talking about silently mis-interpreting it.
>> There is precedent for making valid C code an error because it is error
>> prone.
>
>
> Here's where I'm coming from with this. The problem is that CPU integers
> are 2's complement and a fixed number of bits. We'd like to pretend they
> work just like whole numbers we learned about in 2nd grade arithmetic.
> But they don't, and we can't fix it so they do. I think it's ultimately
> fruitless to try and make them behave other than what they are: 2's
> complement fixed arrays of bits.
>
> So, we wind up with oddities like overflow, wrap-around,
> -int.min==int.min. Heck, we *rely* on these oddities (subtraction
> depends on wrap-around). Sometimes, we pretend these bit values are
> signed, sometimes unsigned, and we mix together those notions in the
> same expression.
One further thing I'll say on this:
signed computer math makes a lot of sense to people because the limits are
so large. For instance, -2 billion to 2 billion. It seems logical that a
computer can't just keep coming up with new bits to represent numbers, but
it seems so far off that an integer will wrap at 2 billion. But unsigned
math has a much more familiar boundary -- zero. Numbers are far more
likely to be near zero than they are near 2 billion or -2 billion.
Applying a negation operator to an unsigned value almost *guarantees*
wrapping past that boundary. 99% of the time, when I apply a negative
sign to a number, I want the negative equivalent of that number. I don't
want some large bizarre value that has no relation to that number, despite
what the computer thinks is sane. I'd look at applying a negation
operator to an unsigned int with as much scrutiny as I'd look at
multiplying an integer by 1_000_000_000. It's almost guaranteed to go out
of bounds, why are you doing it?
Bringing up -int.min == int.min is exactly my point. For integers, there
is one value that the negation operator doesn't work as expected. For
unsigned integers, there is only one number that *does* work as expected
-- zero. All others either don't work as expected, or rely on the
computer behaving strangely (if it is indeed expected). To make such rare
purposeful uses more explicit does not lower the quality of code or the
ease of use.
-Steve
More information about the Digitalmars-d
mailing list