By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
446,367 Members | 1,327 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 446,367 IT Pros & Developers. It's quick & easy.

what exactly is the difference between signed and unsigned in C?

P: n/a
Hi all,

I am not clear what is the difference between signed and unsigned
in C. Many say, unsigned means only +ve values and 0.

Can I use unsigned int i = -3?
What happens internally ? What conversion happens?
Also on 32 and 64bit machines what happens?

Can anybody explain?

Nov 14 '05 #1
Share this Question
Share on Google+
5 Replies


P: n/a
<ra********@yahoo.com> wrote in message
news:11**********************@c13g2000cwb.googlegr oups.com...
I am not clear what is the difference between signed and unsigned
in C. Many say, unsigned means only +ve values and 0.

Can I use unsigned int i = -3?
Yes.
What happens internally ? What conversion happens?
Conversion of a value to any unsigned type is conceptually performed by
repeatedly adding or subtracting <maximum value for type>+1 until the result
lies between 0 and <maximum value for type> inclusive.

If UINT_MAX (defined in <limits.h>), the maximum value for an unsigned int,
is 65535, then this:

#include <stdio.h>
int main(void) {
unsigned int i = -3;
printf("%u\n", i);
return 0;
}

will output 65533, since -3 + (65535+1) = 65533.

If UINT_MAX = 4294967295 (common on 32- and 64-bit platforms), the output
will be 4294967293.
Also on 32 and 64bit machines what happens?


The only difference the platform makes to the above conversion is due to the
possible difference in UINT_MAX (assuming the compiler is conforming). Is
that what you were asking?

Alex
Nov 14 '05 #2

P: n/a

<ra********@yahoo.com> wrote
I am not clear what is the difference between signed and unsigned
in C. Many say, unsigned means only +ve values and 0.

Can I use unsigned int i = -3?
What happens internally ? What conversion happens?
Also on 32 and 64bit machines what happens?

Can anybody explain?

Almost all computers use two's complement notation. This means that to
negate an integer you invert the bits, and then add one, losing the overflow
if any. so 1 becomes 11111110 and then 11111111 (all bits set). Zero becomes
11111111 and then overflows to 00000000, which is correct, -0 equals 0.

Internally the processor often has no concept of negative numbers. This is
because adding and throwing away the overflow, in two's complement, is
exactly the same as negating and subtracting.

However the C standard doesn't guarantee that two's complement will be used.
So we have the situation that trying to express -3 as an unsigned integer is
probably going to produce its twos complement value 11111101 (right extend
the ones to sixteen of thirty-two bits instead of eight), which is a
largeish unsigned value. However you cannot be sure of this, and sometimes
you might manage to trigger an internal trap. So from the point of view of
the C stnadard it is actually better to forget all you know about two's
complement values, and just assume that trying to express a negative integer
as an unsigned is illegal.
Nov 14 '05 #3

P: n/a
"Malcolm" <ma*****@55bank.freeserve.co.uk> writes:
[...]
However the C standard doesn't guarantee that two's complement will be used.
So we have the situation that trying to express -3 as an unsigned integer is
probably going to produce its twos complement value 11111101 (right extend
the ones to sixteen of thirty-two bits instead of eight), which is a
largeish unsigned value. However you cannot be sure of this, and sometimes
you might manage to trigger an internal trap. So from the point of view of
the C stnadard it is actually better to forget all you know about two's
complement values, and just assume that trying to express a negative integer
as an unsigned is illegal.


Conversion from signed to unsigned is well-defined in C. It's defined
in terms of values, not in terms of the underlying representation.

Conceptionally, converting a signed value to "unsigned int" is done by
repeatedly or subtracting UINT_MAX+1 until the result is within range.
For example, assuming 16-bit int, (unsigned)-3 is computed by adding
65536 to the mathematical value, yielding 65533.

It happens that this is easy to implement on a 2's-complement system,
but the same requirement applies to other systems (though they're
rare).

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Nov 14 '05 #4

P: n/a
To answer your question a bit more expansively, unsigned and signed
ints are treated differently in terms of what condition flags are used
to evaluate them per C relational operators.

In plain english this means that a>b may have different answers
depending on whether a and b are signed, unsigned, or mixed.

Nov 14 '05 #5

P: n/a
Novitas wrote:
To answer your question a bit more expansively, unsigned and signed
ints are treated differently in terms of what condition flags are used to evaluate them per C relational operators.
What are "condition flags".
In plain english this means that a>b may have different answers
depending on whether a and b are signed, unsigned, or mixed.


That's not very expansive :)
If a and b are both signed, or both unsigned, there is no confusion.
If one is signed and one isn't, then the signed one is promoted to
unsigned (via the process described by Keith Thompson in this thread).

The same goes for the other arithmetic binary operators
(but not the bitwise binary operators).

Nov 14 '05 #6

This discussion thread is closed

Replies have been disabled for this discussion.