Solved

Comparing unsigned int and int: ranking order when converting??

Posted on 2013-12-02
6
424 Views
Last Modified: 2013-12-08
Ah hello.

I have been reading about comparing signed and unsigned integers on https://www.securecoding.cert.org/confluence/display/seccode/INT02-C.+Understand+integer+conversion+rules.  This page gives a simple example:

int si = -1;
unsigned int ui = 1;
printf("%d\n", si < ui);

Open in new window


The output is 0, not 1 as might be initially believed, as the int s1 is converted to an unsigned int with value UINT_MAX.

This is something to do with conversion rules and integer ranking; I roughly understand the conversion rules ("Usual Arithmetic Conversions" section on the link) - and believe that rule #3 is being used:

If the operand that has unsigned integer type has rank greater than or equal to the rank of the type of the other operand, the operand with signed integer type is converted to the type of the operand with unsigned integer type.

...but I don't understand the ranking: clearly for the conversion above to take place the unsigned value has been given a greater rank than the signed value but where is it specified that this will happen??

Can someone please clarify ?

(Sorry if I have missed it from the above link but I have spent a long time looking at this which might be to blame:))
0
Comment
Question by:mrwad99
  • 2
  • 2
  • 2
6 Comments
 
LVL 86

Accepted Solution

by:
jkr earned 250 total points
ID: 39690134
Scroll up a bit from the code snippet you posted, to 'Integer Conversion Rank'

There you'll find the statement:

The rank of any unsigned integer type shall equal the rank of the corresponding signed integer type, if any.

which directly correlates to

If the operand that has unsigned integer type has rank greater than or equal to the rank of the type of the other operand, the operand with signed integer type is converted to the type of the operand with unsigned integer type.

and therefore makes that rule apply.
0
 
LVL 33

Expert Comment

by:sarabande
ID: 39691872
to add to above comment:

actually signed and unsigned integers (of same size) were not really "converted" for compare operations but "reinterpreted", what means that the highest (most significant) bit either was interpreted as sign bit or not.

because of that you could do like

unsigned int ui = -1;  // ui is MAX_UINT
int i = -1;
assert(ui == i);  // expression is true

Open in new window


though the same code would be much  better readable if you do:

unsigned int ui = (unsigned int)(-1);  // ui is MAX_UINT
int i = -1;
assert((int)ui == i);  // expression is true

Open in new window


generally in such cases the direction of the cast should follow the "nature" of the value. so in case of a negative number you should cast the "unsigned" to "signed" and not vice versa.

Sara
0
 
LVL 19

Author Comment

by:mrwad99
ID: 39693722
jkr: thanks for finding what I had missed:)

Woah...time out there Sara!

I am not sure why your first example works: if ui is MAX_UINT then how on earth is that equal to -1; is it because the -1 is being converted to the unsigned int equivalent which is also MAX_UINT??  And if this is true, is it because of the second rule that jkr quoted above: "...the operand with signed integer type is converted to the type of the operand with unsigned integer type"

>> what means that the highest (most significant) bit either was interpreted as sign bit or not

That is really interesting; could you possible elaboate with an example?

>> ...so in case of a negative number you should cast the "unsigned" to "signed" and not vice versa

How come you are casting the uint ui to an int then - or have I misinterpreted your comment??

jkr/Sara:

From the quote jkr made:

"The rank of any unsigned integer type shall equal the rank of the corresponding signed integer type, if any"

Does "corresponding signed integer type" mean "the same numeric value", so "(unsigned int)-1" has the corresponding integer type as "(int)-1". but not the same corresponding integer type as "(int)-2"?  In this case, what rule determines which of (unsigned int)-1 and (int)-2 has the highest rank?

Thanks very much in advance both!
0
Is Your AD Toolbox Looking More Like a Toybox?

Managing Active Directory can get complicated.  Often, the native tools for managing AD are just not up to the task.  The largest Active Directory installations in the world have relied on one tool to manage their day-to-day administration tasks: Hyena. Start your trial today.

 
LVL 86

Expert Comment

by:jkr
ID: 39693741
Nope, the "corresponding signed integer type" means a type with the same precision, i.e. the corresponding signed type to an 'unsigned short' is 'short', to an 'unsigned long' it's long.
0
 
LVL 33

Assisted Solution

by:sarabande
sarabande earned 250 total points
ID: 39696116
a 32-bit integer with all bits set is -1 for signed and is 2^32-1 for unsigned (MAX_UINT == 4294967295). if you add 1 to the number in both cases the result is 0 what is in the second case because of an overflow. 0 means that no bit is set.

all negative numbers of a signed integer have the highest bit (bit 31 for 'int' and 'unsigned int') set to 1. the highest bit of 0 ... 31 is also called the most significant bit as it is responsible for the highest range of numbers from 2^31 to 2^32-1. the 2^31-1 (hex: 0x7FFFFFFF, decimal: 2147483647) is the highest number of a signed integer. if you add 1 to that number you would get -2^31 (decimal -2147483648) for 'int' variable and 2^31 (decimal ) for unsigned int. for both the hex value is 0x80000000 or binary 10000000000000000000000000000000 where the most left bit is 1 and all other are 0.

summary: for 'signed' and 'unsigned' integers with the same bit count we have the same bit combinations which were "interpreted" differently when the highest bit was set.

 "signed"
|---------------|+++++++++++++|
 -2^31 ..... -1 0 ..... 2^31-1 ..... 2^32-1
                |++++++++++++|+++++++++++++|
                "unsigned"

Open in new window


for a signed integer the second part of the unsigned numbers would be interpreted as the negative numbers without any conversion (all bits keep their value).

>> ...so in case of a negative number you should cast the "unsigned" to "signed" and not vice versa

How come you are casting the uint ui to an int then - or have I misinterpreted your comment??

my statement was: if you compare an signed integer with an unsigned integer you could either do a cast on the signed integer or you could cast the unsigned integer to signed. both
cases are equivalent and would make the comparison better readable as now both operands have same type. but if the signed integer could have a negative number - for example because it was a difference - you better do the cast from unsigned to signed and not vice versa such that the "nature" of the value was not changed. in the debugger both sides would show for example -4 rather than 4294967292 or 0xFFFFFFFB then.

Sara
0
 
LVL 19

Author Closing Comment

by:mrwad99
ID: 39704245
Thanks both :)
0

Featured Post

Master Your Team's Linux and Cloud Stack

Come see why top tech companies like Mailchimp and Media Temple use Linux Academy to build their employee training programs.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
GUI: DIalog Stacking and Popping in MS C++ 4 74
Line meaning 9 85
Using popen() and gunzip() to open file in HTTPServer 6 59
VS2015 Redefinition errors 4 51
When writing generic code, using template meta-programming techniques, it is sometimes useful to know if a type is convertible to another type. A good example of when this might be is if you are writing diagnostic instrumentation for code to generat…
Templates For Beginners Or How To Encourage The Compiler To Work For You Introduction This tutorial is targeted at the reader who is, perhaps, familiar with the basics of C++ but would prefer a little slower introduction to the more ad…
The goal of this video is to provide viewers with basic examples to understand how to use strings and some functions related to them in the C programming language.
The goal of the tutorial is to teach the user how to use functions in C++. The video will cover how to define functions, how to call functions and how to create functions prototypes. Microsoft Visual C++ 2010 Express will be used as a text editor an…

770 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question