# unsigned == signed ?

Discussion in 'C Programming' started by Raj Pashwar, Oct 11, 2011.

1. ### Raj PashwarGuest

int main()
{
uint x = -1;
int y = -1;
if (x == y)
printf("EQUAL");
else
printf("NOT EQUAL");
}

This code prints "EQUAL". Does this mean that bit comparison is done for
the
equality test? If it doesn't can you give me an example that shows bit
comparison isn't done? I also wanted to know if we can assign a number to
uint & int variables such that "unit var != int var". Thanks so much
Raj Pashwar, Oct 11, 2011

2. ### Keith ThompsonGuest

Raj Pashwar <> writes:
> int main()
> {
> uint x = -1;
> int y = -1;
> if (x == y)
> printf("EQUAL");
> else
> printf("NOT EQUAL");
> }
>
> This code prints "EQUAL". Does this mean that bit comparison is done for
> the
> equality test? If it doesn't can you give me an example that shows bit
> comparison isn't done? I also wanted to know if we can assign a number to
> uint & int variables such that "unit var != int var". Thanks so much

There is no predefined type "uint" in C. I'll assume you meant
"unsigned int".

Here's a corrected version of your program:

#include <stdio.h>

int main(void)
{
unsigned int x = -1;
int y = -1;
if (x == y) {
printf("EQUAL\n");
}
else {
printf("NOT EQUAL\n");
}
return 0;
}

There's actually a fair amount of stuff going on here, some of it
not obvious.

The expression "-1" is of type int. The initialization applies an
implicit conversion from int to unsigned int. The rules for such
a conversion (see C99 6.3.1.3p2) mean that the initial value of
x is UINT_MAX. (This is probably 4294967295 on a typical 32-bit
system, but other values are possible.)

The comparison "x == y" is comparing an unsigned int value to a
(signed) int value. Before the comparison is performed, the
"usual arithmetic conversions" are applied to the operands (C99
6.5.9p4, 6.3.1.8). In this case, the int operand is converted to
unsigned int. Since y's value is -1, the result is the same as
the result of the conversion in x's initialization.

The result is that "x == y" is comparing UINT_MAX to UINT_MAX,
which of course yields a true value (1).

As it happens, the result is the same that you'd get if the program
just performed bitwise comparisons of the operands. The rules
for conversions and comparisons are defined purely in terms of
the arithmetic *values* of the operands, but the rules are written
in such a way that they can be implemented easily on most systems
(2's-complement representation for signed values).

The latest draft of the C standard is at
http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1256.pdf
(that's a 3.7-megabyte PDF document).

--
Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Keith Thompson, Oct 11, 2011

3. ### James KuyperGuest

On 10/11/2011 03:43 PM, Raj Pashwar wrote:
> int main()
> {
> uint x = -1;

uint is presumably a typedef; it's not a typedef provided by the C
standard itself, so you should have let us know what type it is a
typedef for. I'll presume "unsigned int".

> int y = -1;
> if (x == y)
> printf("EQUAL");
> else
> printf("NOT EQUAL");
> }
>
> This code prints "EQUAL". Does this mean that bit comparison is done for
> the
> equality test?

No, it means that precisely the same conversion is performed on -1 when
it is used to initialize x, as is performed on the value of y when it is
converted to the type of 'x' for the comparison. Assuming that uint is a
typedef for unsigned int, the result is guaranteed to be UINT_MAX in
both cases.

> ... If it doesn't can you give me an example that shows bit
> comparison isn't done?

Yes. Change 'y' to signed char, and x to unsigned long. If sizeof(signed
char) < sizeof(unsigned long) (which is almost, but not quite, certainly
guaranteed), most of the bits that are set in x won't have any
comparable bits in 'y'. However, the values will still compare equal,
because y's value of -1 will be converted to ULONG_MAX before the
conversion.

In the unlikely event that you can locate an implementation where 'int'
uses a 1's complement or sign-magnitude representation, you'll find that
you still get exactly the same result, which ALSO proves that it's a
value comparison, not a bit comparison. That's because x and y will have
very different bit patterns on such a system.

> ... I also wanted to know if we can assign a number to
> uint & int variables such that "unit var != int var". Thanks so much

Not as long as the number is within the range [INT_MIN, INT_MAX].
Because the same conversions are performed in both cases, the values
necessarily compare equal.
James Kuyper, Oct 11, 2011
4. ### Quentin PopeGuest

On Tue, 11 Oct 2011 19:43:03 +0000, Raj Pashwar wrote:
> int main()
> {
> uint x = -1;
> int y = -1;
> if (x == y)
> printf("EQUAL");
> else
> printf("NOT EQUAL");
> }
>
> This code prints "EQUAL". Does this mean that bit comparison is done for
> the
> equality test? If it doesn't can you give me an example that shows bit
> comparison isn't done?

no ! unsigned int, and signed int are very different the way they are
represented in bits. therefore, when you to compare the 2 different types
(like comparing apples and oranges) one of them has to be converted, in
this
case, the 'int' is converted to a 'uint', and becomes 0, since unsigned
numbers cannot be less then zero.
and besides, the == operator it *not* a bit comparison operator, it is a
variable comparison operator, if you want to do bit comparison you use the
bitwise operators, &,|,^,~. (and, or, exclusive or, not. respectively)

> I also wanted to know if we can assign a number
> to uint & int variables such that "unit var != int var". Thanks so much

yes, if unit var = 1, and int var is any value other than 1 (-1, 0, -10,
10,
100, whatever) then they will be 'not equal' if you use the operator '!='
for example:

uint x = 1;
int y = -1;
if (x == y)
printf("EQUAL");
else
printf("NOT EQUAL");

will print NOT EQUAL since y is converted to an unsigned int and becomes
0
Quentin Pope, Oct 11, 2011
5. ### James KuyperGuest

On 10/11/2011 04:33 PM, Quentin Pope wrote:
> On Tue, 11 Oct 2011 19:43:03 +0000, Raj Pashwar wrote:

....
>> I also wanted to know if we can assign a number
>> to uint & int variables such that "unit var != int var". Thanks so much

>
> yes, if unit var = 1, and int var is any value other than 1 (-1, 0, -10,
> 10,
> 100, whatever) then they will be 'not equal' if you use the operator '!='
> for example:
>
> uint x = 1;
> int y = -1;

You've not using the same initializer for x and for y; I believe that's
what he meant when he referred to assigning "a number to" both variables.
James Kuyper, Oct 11, 2011
6. ### Keith ThompsonGuest

Quentin Pope <> writes:
> On Tue, 11 Oct 2011 19:43:03 +0000, Raj Pashwar wrote:
>> int main()
>> {
>> uint x = -1;
>> int y = -1;
>> if (x == y)
>> printf("EQUAL");
>> else
>> printf("NOT EQUAL");
>> }
>>
>> This code prints "EQUAL". Does this mean that bit comparison is done for
>> the
>> equality test? If it doesn't can you give me an example that shows bit
>> comparison isn't done?

>
> no ! unsigned int, and signed int are very different the way they are
> represented in bits.

They're not all that different. In fact, in the absence of padding bits
and/or trap representations, the language guarantees that a value that's
representable as int and unsigned int (i.e., in the range 0 .. INT_MAX)
has the same representation in both types.

> therefore, when you to compare the 2 different types
> (like comparing apples and oranges) one of them has to be converted, in
> this
> case, the 'int' is converted to a 'uint', and becomes 0, since unsigned
> numbers cannot be less then zero.

It's true that one of them is converted. This is because the language
standard says so; it's not a consequence of their representations. The
language *could* have defined "==" as a bitwise comparison (and in fact
that would have yielded the same results for int vs. unsigned int
comparisonms on 2's-complement systems).

But you're mistaken about the semantics of the conversion. When an
integer value is converted to an unsigned type, and the value cannot be
represented in the target type, " the value is converted by repeatedly
adding or subtracting one more than the maximum value that can be
represented in the new type until the value is in the range of the new
type" (C99 6.3.1.3p2). In this particular case, convering the int value
-1 to unsigned int yields UINT_MAX.

> and besides, the == operator it *not* a bit comparison operator, it is a
> variable comparison operator, if you want to do bit comparison you use the
> bitwise operators, &,|,^,~. (and, or, exclusive or, not. respectively)

It's more accurate to say that it's a *value* comparison operator; there
needn't be any variables involved (consider "1 + 1 == 2").

The bitwise operators don't do comparisons. If you want to do
a bitwise equality comparison, the memcmp() function is probably
the best approach. Or you could treat the objects as arrays of
unsigned char and compare the element values (that's basically what
memcmp() does).

>> I also wanted to know if we can assign a number
>> to uint & int variables such that "unit var != int var". Thanks so much

>
> yes, if unit var = 1, and int var is any value other than 1 (-1, 0, -10,
> 10,
> 100, whatever) then they will be 'not equal' if you use the operator '!='
> for example:
>
> uint x = 1;
> int y = -1;
> if (x == y)
> printf("EQUAL");
> else
> printf("NOT EQUAL");
>
> will print NOT EQUAL since y is converted to an unsigned int and becomes
> 0

No, it will print NOT EQUAL because y is converted to an unsigned int
and becomes UINT_MAX (typically 4294967295), which is not equal to 1.
You'd get the same result if "==" did a bitwise comparison.

--
Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Keith Thompson, Oct 11, 2011
7. ### Ben BacarisseGuest

Quentin Pope <> writes:

> On Tue, 11 Oct 2011 19:43:03 +0000, Raj Pashwar wrote:
>> int main()
>> {
>> uint x = -1;
>> int y = -1;
>> if (x == y)
>> printf("EQUAL");
>> else
>> printf("NOT EQUAL");
>> }
>>
>> This code prints "EQUAL". Does this mean that bit comparison is done for
>> the
>> equality test? If it doesn't can you give me an example that shows bit
>> comparison isn't done?

>
> no ! unsigned int, and signed int are very different the way they are
> represented in bits. therefore, when you to compare the 2 different types
> (like comparing apples and oranges) one of them has to be converted, in
> this
> case, the 'int' is converted to a 'uint', and becomes 0, since unsigned
> numbers cannot be less then zero.

Not zero, but UINT_MAX.

> and besides, the == operator it *not* a bit comparison operator, it is a
> variable comparison operator, if you want to do bit comparison you use the
> bitwise operators, &,|,^,~. (and, or, exclusive or, not. respectively)
>
>> I also wanted to know if we can assign a number
>> to uint & int variables such that "unit var != int var". Thanks so much

>
> yes, if unit var = 1, and int var is any value other than 1 (-1, 0, -10,
> 10,
> 100, whatever) then they will be 'not equal' if you use the operator '!='
> for example:
>
> uint x = 1;
> int y = -1;
> if (x == y)
> printf("EQUAL");
> else
> printf("NOT EQUAL");
>
> will print NOT EQUAL since y is converted to an unsigned int and becomes
> 0

See above!

--
Ben.
Ben Bacarisse, Oct 11, 2011
8. ### J. J. FarrellGuest

Quentin Pope wrote:
> On Tue, 11 Oct 2011 19:43:03 +0000, Raj Pashwar wrote:
>> int main()
>> {
>> uint x = -1;
>> int y = -1;
>> if (x == y)
>> printf("EQUAL");
>> else
>> printf("NOT EQUAL");
>> }
>>
>> This code prints "EQUAL". Does this mean that bit comparison is done
>> for the equality test? If it doesn't can you give me an example that
>> shows bit comparison isn't done?

>
> no ! unsigned int, and signed int are very different the way they are
> represented in bits. therefore, when you to compare the 2 different types
> (like comparing apples and oranges) one of them has to be converted, in
> this case, the 'int' is converted to a 'uint', and becomes 0, since
> unsigned numbers cannot be less then zero.

Is this meant to be a joke? Or is -1 equal to 0 where you come from?

> ...
J. J. Farrell, Oct 12, 2011
9. ### Quentin PopeGuest

On Tue, 11 Oct 2011 14:34:29 -0700, Keith Thompson wrote:

> Quentin Pope <> writes:
>> On Tue, 11 Oct 2011 19:43:03 +0000, Raj Pashwar wrote:
>>> int main()
>>> {
>>> uint x = -1;
>>> int y = -1;
>>> if (x == y)
>>> printf("EQUAL");
>>> else
>>> printf("NOT EQUAL");
>>> }
>>>
>>> This code prints "EQUAL". Does this mean that bit comparison is done
>>> for the
>>> equality test? If it doesn't can you give me an example that shows bit
>>> comparison isn't done?

>>
>> no ! unsigned int, and signed int are very different the way they are
>> represented in bits.

>
> They're not all that different. In fact, in the absence of padding bits
> and/or trap representations, the language guarantees that a value that's
> representable as int and unsigned int (i.e., in the range 0 .. INT_MAX)
> has the same representation in both types.
>
>> therefore, when you to compare the 2 different
>> types
>> (like comparing apples and oranges) one of them has to be converted, in
>> this
>> case, the 'int' is converted to a 'uint', and becomes 0, since unsigned
>> numbers cannot be less then zero.

>
> It's true that one of them is converted. This is because the language
> standard says so; it's not a consequence of their representations. The
> language *could* have defined "==" as a bitwise comparison (and in fact
> that would have yielded the same results for int vs. unsigned int
> comparisonms on 2's-complement systems).
>
> But you're mistaken about the semantics of the conversion. When an
> integer value is converted to an unsigned type, and the value cannot be
> represented in the target type, " the value is converted by repeatedly
> adding or subtracting one more than the maximum value that can be
> represented in the new type until the value is in the range of the new
> type" (C99 6.3.1.3p2). In this particular case, convering the int value
> -1 to unsigned int yields UINT_MAX.
>
>> and besides, the == operator it *not* a bit comparison operator, it is
>> a variable comparison operator, if you want to do bit comparison you
>> use the bitwise operators, &,|,^,~. (and, or, exclusive or, not.
>> respectively)

>
> It's more accurate to say that it's a *value* comparison operator; there
> needn't be any variables involved (consider "1 + 1 == 2").
>
> The bitwise operators don't do comparisons. If you want to do a bitwise
> equality comparison, the memcmp() function is probably the best
> approach. Or you could treat the objects as arrays of unsigned char and
> compare the element values (that's basically what memcmp() does).
>
>>> I also wanted to know if we can assign a number to uint & int
>>> variables such that "unit var != int var". Thanks so much

>>
>> yes, if unit var = 1, and int var is any value other than 1 (-1, 0,
>> -10, 10,
>> 100, whatever) then they will be 'not equal' if you use the operator
>> '!=' for example:
>>
>> uint x = 1;
>> int y = -1;
>> if (x == y)
>> printf("EQUAL");
>> else
>> printf("NOT EQUAL");
>>
>> will print NOT EQUAL since y is converted to an unsigned int and
>> becomes 0

>
> No, it will print NOT EQUAL because y is converted to an unsigned int
> and becomes UINT_MAX (typically 4294967295), which is not equal to 1.
> You'd get the same result if "==" did a bitwise comparison.

true, my mistake.
however the values are converted first. to prove it, try this
long x = -1; /* (32 bit, signed) */
unit y = -1; /* (16 bit, unsigned) */
if (x == y) printf("EQUAL");
will print EQUAL !
Quentin Pope, Oct 12, 2011
10. ### James KuyperGuest

On 10/12/2011 12:04 PM, Quentin Pope wrote:
....
> true, my mistake.
> however the values are converted first. to prove it, try this
> long x = -1; /* (32 bit, signed) */
> unit y = -1; /* (16 bit, unsigned) */

uint?

> if (x == y) printf("EQUAL");
> will print EQUAL !

Of course, and that's fully consistent with what Keith said.
James Kuyper, Oct 12, 2011
11. ### Keith ThompsonGuest

Quentin Pope <> writes:
> On Tue, 11 Oct 2011 14:34:29 -0700, Keith Thompson wrote:
>> Quentin Pope <> writes:

[...]
>>> uint x = 1;
>>> int y = -1;
>>> if (x == y)
>>> printf("EQUAL");
>>> else
>>> printf("NOT EQUAL");
>>>
>>> will print NOT EQUAL since y is converted to an unsigned int and
>>> becomes 0

>>
>> No, it will print NOT EQUAL because y is converted to an unsigned int
>> and becomes UINT_MAX (typically 4294967295), which is not equal to 1.
>> You'd get the same result if "==" did a bitwise comparison.

>
> true, my mistake.
> however the values are converted first. to prove it, try this
> long x = -1; /* (32 bit, signed) */
> unit y = -1; /* (16 bit, unsigned) */

What makes you think that long is 32 bits and uint (unsigned int?) is
16 bits? They're *at least* those widths, but they could be wider.
(I suspect that int is actually 32 bits on your system.)

> if (x == y) printf("EQUAL");
> will print EQUAL !

Not if long is wider than int, as you assert. (More precisely, not
if long can represent all the values of unsigned int.) On such
a system, y will be initialized to UINT_MAX, which is 65535.
In the comparison, the "usual arithmetic conversions" will promote
the value of y from unsigned int to (signed) long, resulting in
an equality comparison between 65535 and -1, both of type long.
It will not print "EQUAL".

On the other hand, if int and long are both 32 bits, then both x
and y are converted to unsigned long, so the comparison is between
ULONG_MAX and ULONG_MAX; in that case, it will print "EQUAL".

And why do you insist on using the name "uint"? We've said before
that there is no such predefined type in C. If you mean "unsigned
int", please say "unsigned int". If you really want to call it
"uint", provide a typedef. (For all we know, "uint" could be a
typedef for _Bool.)

--
Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Keith Thompson, Oct 12, 2011
12. ### Phil CarmodyGuest

Raj Pashwar <> writes:
> int main()
> {
> uint x = -1;
> int y = -1;
> if (x == y)
> printf("EQUAL");
> else
> printf("NOT EQUAL");
> }
>
> This code prints "EQUAL". Does this mean that bit comparison is done for
> the
> equality test? If it doesn't can you give me an example that shows bit
> comparison isn't done? I also wanted to know if we can assign a number to
> uint & int variables such that "unit var != int var". Thanks so much

C will only compare equal types. In order to perform what looks
like a comparison between unequal types, an implicit conversion
is made first such that the things actually being compared are
the same type. See the description of the '==' operator in the
standard (google for n1256.pdf if you don't already have a copy).

Phil
--
"Religion is what keeps the poor from murdering the rich."
-- Napoleon
Phil Carmody, Oct 13, 2011
13. ### Phil CarmodyGuest

Ben Bacarisse <> writes:
> Quentin Pope <> writes:
>
> > On Tue, 11 Oct 2011 19:43:03 +0000, Raj Pashwar wrote:
> >> int main()
> >> {
> >> uint x = -1;
> >> int y = -1;
> >> if (x == y)
> >> printf("EQUAL");
> >> else
> >> printf("NOT EQUAL");
> >> }
> >>
> >> This code prints "EQUAL". Does this mean that bit comparison is done for
> >> the
> >> equality test? If it doesn't can you give me an example that shows bit
> >> comparison isn't done?

> >
> > no ! unsigned int, and signed int are very different the way they are
> > represented in bits. therefore, when you to compare the 2 different types
> > (like comparing apples and oranges) one of them has to be converted, in
> > this
> > case, the 'int' is converted to a 'uint', and becomes 0, since unsigned
> > numbers cannot be less then zero.

>
> Not zero, but UINT_MAX.

He looks like he's under the misapprehension that the conversion is a
saturating one (anything that goes out of bounds gets mapped onto the
value just inside the bound that was exceeded.

So I think the better correction is the mathematical expression
UINT_MAX+1+x
Which for x==-1 is UINT_MAX, as you say.
But for x==2 it's UINT_MAX-1, etc.

> > and besides, the == operator it *not* a bit comparison operator, it is a
> > variable comparison operator, if you want to do bit comparison you use the
> > bitwise operators, &,|,^,~. (and, or, exclusive or, not. respectively)
> >
> >> I also wanted to know if we can assign a number
> >> to uint & int variables such that "unit var != int var". Thanks so much

> >
> > yes, if unit var = 1, and int var is any value other than 1 (-1, 0, -10,
> > 10,
> > 100, whatever) then they will be 'not equal' if you use the operator '!='
> > for example:
> >
> > uint x = 1;
> > int y = -1;
> > if (x == y)
> > printf("EQUAL");
> > else
> > printf("NOT EQUAL");
> >
> > will print NOT EQUAL since y is converted to an unsigned int and becomes
> > 0

>
> See above!

Yup, I'm sure he thinks it saturates.

Phil
--
"Religion is what keeps the poor from murdering the rich."
-- Napoleon
Phil Carmody, Oct 13, 2011
14. ### Ben BacarisseGuest

Phil Carmody <> writes:

> Ben Bacarisse <> writes:
>> Quentin Pope <> writes:
>>
>> > On Tue, 11 Oct 2011 19:43:03 +0000, Raj Pashwar wrote:
>> >> int main()
>> >> {
>> >> uint x = -1;
>> >> int y = -1;
>> >> if (x == y)
>> >> printf("EQUAL");
>> >> else
>> >> printf("NOT EQUAL");
>> >> }
>> >>
>> >> This code prints "EQUAL". Does this mean that bit comparison is done for
>> >> the
>> >> equality test? If it doesn't can you give me an example that shows bit
>> >> comparison isn't done?
>> >
>> > no ! unsigned int, and signed int are very different the way they are
>> > represented in bits. therefore, when you to compare the 2 different types
>> > (like comparing apples and oranges) one of them has to be converted, in
>> > this
>> > case, the 'int' is converted to a 'uint', and becomes 0, since unsigned
>> > numbers cannot be less then zero.

>>
>> Not zero, but UINT_MAX.

>
> He looks like he's under the misapprehension that the conversion is a
> saturating one (anything that goes out of bounds gets mapped onto the
> value just inside the bound that was exceeded.
>
> So I think the better correction is the mathematical expression
> UINT_MAX+1+x
> Which for x==-1 is UINT_MAX, as you say.
> But for x==2 it's UINT_MAX-1, etc.

It is indeed better, but these details had already been explained by
other replies to the OP when I posted. All I was doing was pointing out
an uncorrected detail in another reply. (And I was feeling lazy.)

<snip>
--
Ben.
Ben Bacarisse, Oct 13, 2011

### Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.