Thread overview | |||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
June 19, 2006 Integer promotion... what I'm missing? (It's monday...) | ||||
---|---|---|---|---|
| ||||
Hi all, What I'm missing? uint a = 16; int b = -1; assert( b < a ); // this fails! I was expecting that -1 < 16 Thanks --- Paolo |
June 19, 2006 Re: Integer promotion... what I'm missing? (It's monday...) | ||||
---|---|---|---|---|
| ||||
Posted in reply to Paolo Invernizzi | Paolo Invernizzi wrote: > Hi all, > > What I'm missing? > > uint a = 16; > int b = -1; > assert( b < a ); // this fails! I was expecting that -1 < 16 > > Thanks > > --- > Paolo If you read http://digitalmars.com/d/type.html, you will find the rules for integer promotion under arithmetic operations (which I assume also includes comparisons). Note point 5.4 under "Usual Arithmetic Conversions": 5.4. The signed type is converted to the unsigned type. Hence, b is being converted to a uint. cast(uint)(-1) = ~0 = uint.max, hence why b is not less than a. If you're going to compare a signed and unsigned type directly, it's best to explicitly cast them to a common type, or strange things like this could happen :) Either convert a to an int (and watch for overflow), or convert them both to a long (so you don't have problems with overflow). -- Daniel -- Unlike Knuth, I have neither proven or tried the above; it may not even make sense. v2sw5+8Yhw5ln4+5pr6OFPma8u6+7Lw4Tm6+7l6+7D i28a2Xs3MSr2e4/6+7t4TNSMb6HTOp5en5g6RAHCP http://hackerkey.com/ |
June 19, 2006 Re: Integer promotion... what I'm missing? (It's monday...) | ||||
---|---|---|---|---|
| ||||
Posted in reply to Daniel Keep | "Daniel Keep" <daniel.keep.lists@gmail.com> wrote in message news:e75qg4$2bt$1@digitaldaemon.com... > > > Paolo Invernizzi wrote: >> Hi all, >> >> What I'm missing? >> >> uint a = 16; >> int b = -1; >> assert( b < a ); // this fails! I was expecting that -1 < 16 >> >> Thanks >> >> --- >> Paolo > > If you read http://digitalmars.com/d/type.html, you will find the rules for integer promotion under arithmetic operations (which I assume also includes comparisons). > > Note point 5.4 under "Usual Arithmetic Conversions": > > 5.4. The signed type is converted to the unsigned type. > > Hence, b is being converted to a uint. cast(uint)(-1) = ~0 = uint.max, > hence why b is not less than a. > > If you're going to compare a signed and unsigned type directly, it's best to explicitly cast them to a common type, or strange things like this could happen :) Either convert a to an int (and watch for overflow), or convert them both to a long (so you don't have problems with overflow). > > -- Daniel I believe it is a mistake to have an operation like this occur when it is both mathematically incorrect and unintuitive. It feels like something that is destined to be a Bug Breeder. I would prefer that any type promotions (and any implicit operations for that matter) should guarantee not to introduce any data corruption. In this case, promote both numbers to a third type which can hold all possible values from both. If the user wishes to override that by making explicit conversions, at least this will be visible in the code. Tony Melbourne, Australia |
June 19, 2006 Re: Integer promotion... what I'm missing? (It's monday...) | ||||
---|---|---|---|---|
| ||||
Posted in reply to Tony | Tony wrote:
> I would prefer that any type promotions (and any implicit operations for that matter) should guarantee not to introduce any data corruption. In this case, promote both numbers to a third type which can hold all possible values from both.
I agree!
Perhaps this could also prevent the "array.length-1" bug (which is ~0 when array.length == 0), by making "array.length-1" a "long" instead of a "uint".
L.
|
June 19, 2006 Re: Integer promotion... what I'm missing? (It's monday...) | ||||
---|---|---|---|---|
| ||||
Posted in reply to Tony | On Mon, 19 Jun 2006 20:11:32 +1000, Tony <ignorethis@nowhere.com> wrote: >> If you read http://digitalmars.com/d/type.html, you will find the rules >> for integer promotion under arithmetic operations (which I assume also >> includes comparisons). >> >> Note point 5.4 under "Usual Arithmetic Conversions": >> >> 5.4. The signed type is converted to the unsigned type. . . . > I believe it is a mistake to have an operation like this occur when it is > both mathematically incorrect and unintuitive. It feels like something that is destined to be a Bug Breeder. No argument from me. This has often caused me grief. The two most often gotchas for me is mismatched template parameters due to this stupid rule, and that array length is a uint which means that all expressions involving array.length get silently converted to uint before the evaluation and that can mess up index accesses. -- Derek Parnell Melbourne, Australia |
June 19, 2006 Re: Integer promotion... what I'm missing? (It's monday...) | ||||
---|---|---|---|---|
| ||||
Posted in reply to Tony | Tony wrote:
> I would prefer that any type promotions (and any implicit operations for that matter) should guarantee not to introduce any data corruption. In this case, promote both numbers to a third type which can hold all possible values from both.
>
What should be done when one number is an ulong too big to fit in a long and the other is a negative number? (Replace "long" with "cent" if we ever get the type.) No matter how the promotion is done, corruption occurs.
I think a warning for all such cases would suffice --- I thought one would be emitted for the original code, but evidently not.
|
June 19, 2006 Re: Integer promotion... what I'm missing? (It's monday...) | ||||
---|---|---|---|---|
| ||||
Posted in reply to Deewiant | Deewiant wrote:
> Tony wrote:
>> I would prefer that any type promotions (and any implicit operations for that matter) should guarantee not to introduce any data corruption. In this case, promote both numbers to a third type which can hold all possible values from both.
>>
> I think a warning for all such cases would suffice --- I thought one would be
> emitted for the original code, but evidently not.
Instead of a warning, I would prefer an error, forcing for an explicit cast if the comparison it's what you really want to to. But only for rule number 4.
Cheers
---
Paolo
|
June 19, 2006 Re: Integer promotion... what I'm missing? (It's monday...) | ||||
---|---|---|---|---|
| ||||
Posted in reply to Paolo Invernizzi | Paolo Invernizzi wrote: > Instead of a warning, I would prefer an error, forcing for an explicit cast if the comparison it's what you really want to to. But only for rule number 4. I'd also like DMD to issue an error in this case, as I've stumbled upon it a few times. -- Tomasz Stachowiak /+ a.k.a. h3r3tic +/ |
June 20, 2006 Re: Integer promotion... what I'm missing? (It's monday...) | ||||
---|---|---|---|---|
| ||||
Posted in reply to Paolo Invernizzi | On Tue, 20 Jun 2006 04:06:37 +0200, Paolo Invernizzi wrote: > Deewiant wrote: >> Tony wrote: >>> I would prefer that any type promotions (and any implicit operations for that matter) should guarantee not to introduce any data corruption. In this case, promote both numbers to a third type which can hold all possible values from both. >>> >> I think a warning for all such cases would suffice --- I thought one would be emitted for the original code, but evidently not. > > Instead of a warning, I would prefer an error, forcing for an explicit cast if the comparison it's what you really want to to. But only for rule number 4. > Just to note that with DMD, a 'warning' is really an optional error. In other words, if you have -w switch and it displays a 'warning', the compiler still fails to create the object file because it treats such warnings as if they were errors. -- Derek (skype: derek.j.parnell) Melbourne, Australia "Down with mediocrity!" 20/06/2006 11:04:06 AM |
June 27, 2006 Re: Integer promotion... what I'm missing? (It's monday...) | ||||
---|---|---|---|---|
| ||||
Posted in reply to Paolo Invernizzi | If you take a look at how comparison works, you'll know why this one fails.
Lets take an uint a = 16; as in your example:
00000000 00000000 00000000 00010000
And now a signed integer with the value -1:
10000000 00000000 00000000 00000001
You might guess which number is bigger, when our comparison is done binary (and after all, that's what the processor does) :)
Regards,
Alex
Paolo Invernizzi wrote:
> Hi all,
>
> What I'm missing?
>
> uint a = 16;
> int b = -1;
> assert( b < a ); // this fails! I was expecting that -1 < 16
>
> Thanks
>
> ---
> Paolo
|
Copyright © 1999-2021 by the D Language Foundation