Unsigned int

  • Thread starter Vijay Kumar R Zanvar
  • Start date
V

Vijay Kumar R Zanvar

Have a look at the follwing program....
main()
{
unsigned int i = -1;
printf("%u\n", i);
}

Why it prints some big number?
 
N

Nicolai Hansen

Vijay Kumar R Zanvar said:
Have a look at the follwing program....
main()
{
unsigned int i = -1;
printf("%u\n", i);
}

Why it prints some big number?

I'm sure you also get a compiler warning.

You assign a negative number to an unsigned integer, this negative number is
just being assigned as good as the compiler can do it (which is the maximum
number of an integer).
 
M

Mac

I'm sure you also get a compiler warning.

You assign a negative number to an unsigned integer, this negative number is
just being assigned as good as the compiler can do it (which is the maximum
number of an integer).

Apart from forgetting to include stdio.h, and not returning a value from
main, what is there to complain about?

I've seen code in this NG where people used -1 as a way of getting all
bits set in an unsigned type. No one complained about it, that I can
recall. So I figured it was an accepted practice.

By all means set me straight if I am wrong. ;-)

Mac
--
 
V

Vijay Kumar R Zanvar

Vijay Kumar R Zanvar said:
Have a look at the follwing program....
main()
{
unsigned int i = -1;
printf("%u\n", i);
}

Why it prints some big number?

Hi,
I am answering myself! :) Probably, I knew the answer. Now
its time to see if I am correct or not! Suggestions welcome.

....

Luckily, these days I am reading the ISO/IEC 9899:1999, the current
C Standard. I will give the answer according to how I understand the
question, and the Standard:

* For unsigned integers, other than unsigned char, the bits of
object representation are divided into two groups:

+ Value bits, and
+ Padding bits

If there are N value bits, then the range of unsigned integer
is 0 to 2^N - 1.

* For signed integers, the bits of the object representation are
divided in the three groups:

+ Value bits
+ Padding bits
+ Sign bit (exactly one bit)

If the sign bit is 0, the object representation of the signed
integer is equal to that of unsigned integer.

Object representation is simply the bit pattern that appears in
the memory of any object, say, int or float or struct.

There is another term used regarding integers: precision.
Precision of an integer type is the number of bits used to
represent a value, except padding and sign bits.

Ex: Precision of
5 is 3 (because 3 bits are needed, i.e., 101)
-1 is 32 (if sizeof (int) == 4 )

The value of padding bits are unspecified as they do not affect
the final result.

With this knowledge, let us see how the following:

unsigned int i = -1;

is represented

See section A6.5 of K&R. It says:

... Otherwise, if either operand is unsigned int, the other
is converted to unsigned int. ...

So, -1 is converted into unsigned integer, which has no sign bit!
-1 is represented in 2's compliment, which is 0xffffffff. If you
store this value in an unsigned type, it is a big value minus sign.

I think, from here onwards you can derive what I mean!

Thanks.
 
P

Peter Nilsson

Vijay Kumar R Zanvar said:
Hi,
I am answering myself! :) Probably, I knew the answer. Now
its time to see if I am correct or not! Suggestions welcome.

...

Luckily, these days I am reading the ISO/IEC 9899:1999, the current
C Standard.

(You obviously haven't got to the part that precludes implicit int and the
use of unprototyped variadic functions without undefined behaviour. ;-)

The text you're looking for is in 6.2.5p9:

"...A computation involving unsigned operands can never overflow,
because a result that cannot be represented by the resulting
unsigned integer type is reduced modulo the number that is one
greater than the largest value that can be represented by the
resulting type."

So, it has nothing to do with representations of signed or unsigned types.
Converting -1 to an unsigned int _must_ produce the largest value that an
unsigned int can represent, namely UINT_MAX.
 
M

Martin Dickopp

Vijay Kumar R Zanvar said:
Hi,
I am answering myself! :) Probably, I knew the answer. Now
its time to see if I am correct or not! Suggestions welcome.

...

Luckily, these days I am reading the ISO/IEC 9899:1999, the current
C Standard.

Good! But the sections you quoted don't apply here.
I will give the answer according to how I understand the question, and
the Standard:

* For unsigned integers, other than unsigned char, the bits of
object representation are divided into two groups:
[...]

The representation is irrelevant here. 6.2.6.1#4 defines what `representation
of a value' means:

Values stored in non-bit-field objects of any other object type consist
of n × CHAR_BIT bits, where n is the size of an object of that type, in
bytes. The value may be copied into an object of type unsigned char [n]
(e.g., by memcpy); the resulting set of bytes is called the object
representation of the value. [...]

You really want 6.3.1.3#2, which describes how an integer value is converted
to an unsigned integer:

Otherwise, if the new type is unsigned, 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.49)
----
Footnote:
49) The rules describe arithmetic on the mathematical value, not the
value of a given type of expression.

In other words, the value is reduced modulo the maximum value plus one, so
that -1 becomes the maximum value.

Martin
 
R

Rick

Hi,

Talking about signed and unsigned stuff, does it makes the performance
better if you carefully choose wether a variable is signed or not? For
example, I got this :

/* do some loop */
int8 counter;
for( counter = 0; counter < MAX_VALUE; counter++ ) {}

That max_value thing is a number between 0..128 so signed int8 and unsigned
int8 both work. But is their also a performance difference?

Greetings,
Rick
 
M

Martin Dickopp

Peter Nilsson said:
The text you're looking for is in 6.2.5p9:

"...A computation involving unsigned operands can never overflow,
because a result that cannot be represented by the resulting
unsigned integer type is reduced modulo the number that is one
greater than the largest value that can be represented by the
resulting type."

I don't think this section applies here. Where's a computation involving
unsigned operands?

Martin
 
M

Martin Dickopp

Rick said:
Hi,

Talking about signed and unsigned stuff, does it makes the performance
better if you carefully choose wether a variable is signed or not? For
example, I got this :

/* do some loop */
int8 counter;
for( counter = 0; counter < MAX_VALUE; counter++ ) {}

That max_value thing is a number between 0..128 so signed int8 and unsigned
int8 both work. But is their also a performance difference?

I would be surprised if simple operations (increment, comparison) on
signed integers have a different performance than the same operations on
the corresponding unsigned integers. Of course, the standard doesn't make
any guarantees either way.

However, performance differences between operations on different integer
types are quite common, so if `int8' is some signed integer type, it is
not necessarily the fastest one. C99 defines the types

int_fast8_t uint_fast8_t
int_fast16_t uint_fast16_t
int_fast32_t uint_fast32_t
int_fast64_t uint_fast64_t

which are the fastest integer types with a width of at least the number in
the type name.

Martin
 
S

Simon Biber

Martin Dickopp said:
[snip]
I don't think this section applies here. Where's a computation
involving unsigned operands?

I agree; the relevant section is C99 6.3.1.3#2:
"Otherwise, if the new type is unsigned, 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."

Since -1 is not within the range of unsigned int, you must add
or subtract UINT_MAX+1 until it is in range. When you add -1 and
UINT_MAX+1 together, you get UINT_MAX.
 
P

Peter Nilsson

Simon Biber said:
Martin Dickopp said:
Have a look at the follwing program....
main()
{
unsigned int i = -1;
printf("%u\n", i);
}

Why it prints some big number?
[snip]
I don't think this section applies here. Where's a computation
involving unsigned operands?

I agree; the relevant section is C99 6.3.1.3#2:
"Otherwise, if the new type is unsigned, 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."

Yup, my bad. I stupidly chose the first goose that quacked like a duck...
 
N

Nicolai Hansen

Apart from forgetting to include stdio.h, and not returning a value from
main, what is there to complain about?

Assigning an out-of-range value to a variable. Like char ch=300;
I've seen code in this NG where people used -1 as a way of getting all
bits set in an unsigned type. No one complained about it, that I can
recall. So I figured it was an accepted practice.

Probably it is. There's nothing wrong with doing it -if you know what
you are doing-. But if you ask on a NG why it's assigned a very large
number, maybe you should refrain from assigning negative values to
unsigned integers :)
 
D

Dan Pop

In said:
Have a look at the follwing program....
main()
{
unsigned int i = -1;
printf("%u\n", i);
}

Why it prints some big number?

Before asking this question, you should have asked yourself another one:
what value should I expect to be printed?

Dan
 
D

Dan Pop

In said:
Talking about signed and unsigned stuff, does it makes the performance
better if you carefully choose wether a variable is signed or not? For
example, I got this :

/* do some loop */
int8 counter;
for( counter = 0; counter < MAX_VALUE; counter++ ) {}

That max_value thing is a number between 0..128 so signed int8 and unsigned
int8 both work.

It must be in the 0..127 interval to be suitable for signed int8.
But is their also a performance difference?

There is no general answer. It depends on the underlying processor and
on the compiler's optimisation abilities.

In theory, counter is promoted to int in either case, so there should be
no visible difference, if the result of the promotion is kept in a
processor register.

In practice, an 8-bit compiler may notice that no promotion is actually
needed and an 8-bit register is enough for storing and incrementing it...

There are other criteria that decide whether to use a signed or unsigned
type for a given purpose, speed is practically never a deciding factor.

As a general rule, prefer signed for normal arithmetic operations and
unsigned for bitwise operations and avoid as much as possible mixing
signed and unsigned in the same expression. But there are frequent
exceptions, especially when the unsigned type size_t is involved via
sizeof or strlen.

Dan
 
D

Dan Pop

Couldn't find something like this in OP's code. What he did was

unsigned int i = -1;

which is assigning a well defined value to i, so there is nothing to
complain about.
How do you know that char can't represent the value 300?

It's a fair guess on conforming hosted implementations.

With one exception, I'm not aware of any system where 9-bit chars
made sense having a conforming implementation. The exception is
that Univac 1100 implementation already (in)famous for using one's
complement for signed integers.

These days, it's freestanding implementations for DSP chips that use
characters the size of the processor word (because there is no decent
support for entities smaller than the word and the thing is not going to
be used for text processing applications, anyway).

Dan
 
B

Barry Schwarz

Assigning an out-of-range value to a variable. Like char ch=300;

Assigning a negative value to an unsigned variable (which is what the
original post discussed) has a well defined meaning in the standard.
It is not at all like assigning a too large value to a signed
variable. By the way, if char defaults to unsigned char, assigning a
too large value also has a well defined meaning in the standard.
Probably it is. There's nothing wrong with doing it -if you know what
you are doing-. But if you ask on a NG why it's assigned a very large
number, maybe you should refrain from assigning negative values to
unsigned integers :)



<<Remove the del for email>>
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
474,102
Messages
2,570,645
Members
47,247
Latest member
GabrieleL2

Latest Threads

Top