Complete newbie, trouble with unsigned ints.
Author Message
Complete newbie, trouble with unsigned ints.

Why doesn't this code return the absolute value of -10?

#include <stdio.h>

int main()
{   unsigned pos;

printf("Enter examination mark: ");
scanf("%u", &pos);
printf("Exam mark entered was: %u", pos);

Quote:
}

I thought the whole purpose of unsigned ints was to return positive
values only, or am I wrong?

BTW If I enter -10, I get 4292967286???

Wed, 02 Feb 2005 15:52:38 GMT
Complete newbie, trouble with unsigned ints.
I don't know what effect has scanf("%u", &pos); when you enter a
negative value...

An unsigned variables can only contain a positive value. By doing, so it
can contain greater numbers because all the bit combinations that were
used for negatives are now positive.

On my system,

unsigned short int i;
i = -1;
printf("%u\n", i);

Gives me 65535

Because the binary for -1 (11111111 11111111b) also represent the
positive value 65535 when using unsigned types.

Using an unsigned type will not calculate absolute values for you.

It gives you a type that only contains positive values. You should do
the conversion yourself what require to read a signed value with scanf
before you put it in an unsigned variable.

Spidy a crit:

Quote:
> Why doesn't this code return the absolute value of -10?

> #include <stdio.h>

> int main()
> {   unsigned pos;

>     printf("Enter examination mark: ");
>     scanf("%u", &pos);
>     printf("Exam mark entered was: %u", pos);
> }

> I thought the whole purpose of unsigned ints was to return positive
> values only, or am I wrong?

> BTW If I enter -10, I get 4292967286???

Wed, 02 Feb 2005 16:55:42 GMT
Complete newbie, trouble with unsigned ints.

Quote:
> Why doesn't this code return the absolute value of -10?
> #include <stdio.h>
> int main()
> {   unsigned pos;

>     printf("Enter examination mark: ");
>     scanf("%u", &pos);
>     printf("Exam mark entered was: %u", pos);
> }
> I thought the whole purpose of unsigned ints was to return positive
> values only, or am I wrong?
> BTW If I enter -10, I get 4292967286???

The conversion from signed to unsigned doesn't work like you think it
does. Most computers use 2's complement representation for integers,
which means that the high bit acts as the sign bit and adding a number
and its negation together gives 0 with carry.
In detail (assuming a 32-bit int), the values from 0x00000000 to
0x7FFFFFFF correspond to the non-negative values 0 to 2147483647,
and the values from 0x8000000000 to 0xFFFFFFFF correspond to the
negative values from -2147483648 to -1. They are in this order.
So your value -10 has the internal representation 0xFFFFFFF6, which
is also the representation of the unsigned value 4294967286.
Unsigned ints have no special sign bits and use each bit as a
value bit.

--

| Kingpriest of "The Flying Lemon Tree" G++ FR FW+ M- #108 D+ ADA N+++|
| http://www.helsinki.fi/~palaste       W++ B OP+                     |
\----------------------------------------- Finland rules! ------------/
- Tailgunner

Wed, 02 Feb 2005 17:07:34 GMT
Complete newbie, trouble with unsigned ints.

Quote:

> Why doesn't this code return the absolute value of -10?

> #include <stdio.h>

> int main()
> {   unsigned pos;

>     printf("Enter examination mark: ");
>     scanf("%u", &pos);
>     printf("Exam mark entered was: %u", pos);
> }

> I thought the whole purpose of unsigned ints was to return positive
> values only, or am I wrong?

> BTW If I enter -10, I get 4292967286???

(-10u) equals (UINT_MAX + 1 - 10)

--
pete

Wed, 02 Feb 2005 17:35:47 GMT
Complete newbie, trouble with unsigned ints.

Quote:

>> BTW If I enter -10, I get 4292967286???

Quote:
>The conversion from signed to unsigned doesn't work like you think it
>does. Most computers use 2's complement representation for integers,
>which means that the high bit acts as the sign bit and adding a number
>and its negation together gives 0 with carry.
>In detail (assuming a 32-bit int), the values from 0x00000000 to
>0x7FFFFFFF correspond to the non-negative values 0 to 2147483647,
>and the values from 0x8000000000 to 0xFFFFFFFF correspond to the
>negative values from -2147483648 to -1. They are in this order.
>So your value -10 has the internal representation 0xFFFFFFF6, which
>is also the representation of the unsigned value 4294967286.
>Unsigned ints have no special sign bits and use each bit as a
>value bit.

More mathematically speaking, C's unsigned integers implement
"clock arithmetic" (so-called because, if you remember the days
of analog clocks :-) , the hands would go around and count from
0 to 11 and then back to 0, or 0 to 59 and then back to 0,
depending on which hand you are looking at).

In this particular case, your computer has 32-bit "unsigned int"s,
which count from 0 to 4294967295 and then cycle back to 0.  The
input value "-10" really means: "give me the number such that,
when adding ten, the result is zero."

Even if your computer were to use something other than two's
complement, C defines "unsigned" arithmetic mathematically, so that
-10 still means "give me the number such that adding ten produces
0", and if UINT_MAX is 4294967295, this remains 4294967286.  In
fact, the number is always exactly UINT_MAX + 1 - 10 -- so if your
UINT_MAX is 65535, the result is 65526, and if your UINT_MAX is
262143, the result is 262134.

This kind of numerical behavior is extremely useful, because it is
100% predictable and easy to extend.  This means that no matter
how obnoxious your system is -- perhaps it implements ones' complement
or sign-and-magnitude -- "unsigned"s will still behave nicely.

(Annoyingly, while K&R-1 C turned "unsigned short"s into "unsigned
int"s, giving fully predictable results, ANSI C turns them into
either signed or unsigned ints depending on the relative values of
USHRT_MAX and UINT_MAX.  So, if you are working with narrow unsigned
types, you may have to use casts or temporary variables to get
--
In-Real-Life: Chris Torek, Wind River Systems (BSD engineering)

Wed, 02 Feb 2005 17:21:10 GMT
Complete newbie, trouble with unsigned ints.

Quote:

> > Why doesn't this code return the absolute value of -10?

> > #include <stdio.h>

> > int main()
> > {   unsigned pos;

> >     printf("Enter examination mark: ");
> >     scanf("%u", &pos);

Instead of the scanf try the direct substitution...

pos = -10;

You should get the same value. Unsigned integer conversion is modulo
UINT_MAX+1. It's not defined as an absolute value.

Quote:
> >     printf("Exam mark entered was: %u", pos);
> > }

> > I thought the whole purpose of unsigned ints was to return positive
> > values only, or am I wrong?

> > BTW If I enter -10, I get 4292967286???

Strictly speaking, the behaviour is undefined since -10 is not in the range
representable by an unsigned int. The scanf family is surprisingly
intollerent to values outside an objects range, as far as the minimum
standard requirements go.

Quote:
> The conversion from signed to unsigned doesn't work like you think it
> does. Most computers use 2's complement representation for integers,
> which means that the high bit acts as the sign bit and adding a number
> and its negation together gives 0 with carry.
> In detail (assuming a 32-bit int), the values from 0x00000000 to
> 0x7FFFFFFF correspond to the non-negative values 0 to 2147483647,
> and the values from 0x8000000000 to 0xFFFFFFFF correspond to the
> negative values from -2147483648 to -1. They are in this order.
> So your value -10 has the internal representation 0xFFFFFFF6, which
> is also the representation of the unsigned value 4294967286.
> Unsigned ints have no special sign bits and use each bit as a
> value bit.

Whilst the above may be true, the general conversion of negative values to
unsigned integers is well defined, irrespective of the representation used
for signed types. When the value -10 is assigned to an unsigned int and
subsequently displayed via %u the output must be the value of UINT_MAX-10+1.

--
Peter

Wed, 02 Feb 2005 17:58:40 GMT
Complete newbie, trouble with unsigned ints.
[Top posting corrected.]

Quote:
> Spidy a crit:
> > Why doesn't this code return the absolute value of -10?

> > #include <stdio.h>

> > int main()
> > {   unsigned pos;

> >     printf("Enter examination mark: ");
> >     scanf("%u", &pos);
> >     printf("Exam mark entered was: %u", pos);
> > }

> > I thought the whole purpose of unsigned ints was to return positive
> > values only, or am I wrong?

> > BTW If I enter -10, I get 4292967286???

> I don't know what effect has scanf("%u", &pos); when you enter a
> negative value...

It's undefined.

Quote:
> An unsigned variables can only contain a positive value. By doing, so it
> can contain greater numbers because all the bit combinations that were
> used for negatives are now positive.

> On my system,

> unsigned short int i;
> i = -1;
> printf("%u\n", i);

> Gives me 65535

> Because the binary for -1 (11111111 11111111b) also represent the
> positive value 65535 when using unsigned types.

The value -1 is converted to 65535 on your system precisely because the
value is converted mathematically modulo UINT_MAX+1, which on your system
would be 65536. Even if your system was sign-magnitude or one's complement,
so long as unsigned int is 16-bits wide, it /must/ give 65535 as an unsigned
value.

Quote:
> Using an unsigned type will not calculate absolute values for you.

> It gives you a type that only contains positive values. You should do
> the conversion yourself what require to read a signed value with scanf
> before you put it in an unsigned variable.

Unlike assignment, scanf is not subject to the same rules of conversion of
negative values. To be strictly portable the OP should read a value as a
string, then use strtoul() to convert the text.

--
Peter

Wed, 02 Feb 2005 17:58:47 GMT
Complete newbie, trouble with unsigned ints.

Quote:

> [Top posting corrected.]

>>Spidy a crit:

>>>Why doesn't this code return the absolute value of -10?

>>>#include <stdio.h>

>>>int main()
>>>{   unsigned pos;

>>>    printf("Enter examination mark: ");
>>>    scanf("%u", &pos);
>>>    printf("Exam mark entered was: %u", pos);
>>>}

>>>I thought the whole purpose of unsigned ints was to return positive
>>>values only, or am I wrong?

>>>BTW If I enter -10, I get 4292967286???

>>I don't know what effect has scanf("%u", &pos); when you enter a
>>negative value...

> It's undefined.

>>An unsigned variables can only contain a positive value. By doing, so it
>>can contain greater numbers because all the bit combinations that were
>>used for negatives are now positive.

>>On my system,

>>unsigned short int i;
>>i = -1;
>>printf("%u\n", i);

>>Gives me 65535

>>Because the binary for -1 (11111111 11111111b) also represent the
>>positive value 65535 when using unsigned types.

> The value -1 is converted to 65535 on your system precisely because the
> value is converted mathematically modulo UINT_MAX+1, which on your system
> would be 65536. Even if your system was sign-magnitude or one's complement,
> so long as unsigned int is 16-bits wide, it /must/ give 65535 as an unsigned
> value.

modulo UINT_MAX+1? Where is the -1 in this equation? Why modulo?

UINT_MAX-10+1

It makes more sense. (Well I supose..)

So the standard is really that strict. I tought this was system
dependent. Anyway the binary representation of negatives is alway the
same for evrery modern computers.

Quote:

>>Using an unsigned type will not calculate absolute values for you.

>>It gives you a type that only contains positive values. You should do
>>the conversion yourself what require to read a signed value with scanf
>>before you put it in an unsigned variable.

> Unlike assignment, scanf is not subject to the same rules of conversion of
> negative values. To be strictly portable the OP should read a value as a
> string, then use strtoul() to convert the text.

I agree.

- Show quoted text -

Quote:

> --
> Peter

Thu, 03 Feb 2005 02:47:32 GMT
Complete newbie, trouble with unsigned ints.

Quote:

> Why doesn't this code return the absolute value of -10?

> #include <stdio.h>

> int main()
> {   unsigned pos;

>     printf("Enter examination mark: ");
>     scanf("%u", &pos);
>     printf("Exam mark entered was: %u", pos);
> }

> I thought the whole purpose of unsigned ints was to return positive
> values only, or am I wrong?

You're right, but not in the way you expected. :-)

Quote:

> BTW If I enter -10, I get 4292967286???

When you assign to an unsigned int, your value is "reduced" modulo
the-largest-number-that-can-fit-in-it-plus-one.

For the sake of illustration, let's pretend we're dealing with a 3-bit
unsigned type whose maximum value is 7. We can think of this type as a
clock:

0
7     1
6       2
5     3
4

(I have no wish to draw a clock with over 4,000,000,000 numerals!)

The clock has 8 numerals, so we are dealing with "modulo 8 arithmetic".
This can also be expressed as "modulo
the-largest-representable-number-plus-one arithmetic", of course.

Okay, let's do some arithmetic with it.

3 + 2 is easy. Start at 3, count 2 places clockwise, and we get 5.
Intuitive. Good.

3 + 5 is just as easy, but not as intuitive. Start at 3, count 5 places
clockwise, and we come to 0. So, in unsigned-int-with-only-three-bits
arithmetic, 3 + 5 is 0. Put another way, 3 + 5 = 0 (modulo 8).

Now let's try some negative numbers. What is 1 - 2? You might expect it
to be -1. Okay, let's find out; start on 1, count two places
ANTI-clockwise, and you get 7. Note that 7 is not the absolute value of
-1!!

Let's try another one: 0 - 10. Start on 0, count ANTI-clockwise 10
places: your counting will hit 7 6 5 4 3 2 1 0 7 6 in that order. So -10
modulo 8 is 6. Not necessarily what you were expecting, but I think you
can see now how it works.

To allow the user to enter a minus sign which you then ignore, you can
use ordinary signed ints, and the abs() function, which is prototyped in
<stdlib.h>

--

"Usenet is a strange place." - Dennis M Ritchie, 29 July 1999.
C FAQ: http://www.eskimo.com/~scs/C-faq/top.html
K&R answers, C books, etc: http://users.powernet.co.uk/eton

Wed, 02 Feb 2005 18:16:40 GMT
Complete newbie, trouble with unsigned ints.
On Sat, 17 Aug 2002 14:47:32 -0400, Alexandre Jasmin

Quote:
> So the standard is really that strict. I tought this was system
> dependent. Anyway the binary representation of negatives is alway the
> same for evrery modern computers.

I assume that you can provide documentation from EVERY MODERN COMPUTER
to back up this assertion?

--
Jack Klein
Home: http://JK-Technology.Com
FAQs for
comp.lang.c http://www.eskimo.com/~scs/C-faq/top.html
comp.lang.c++ http://www.parashift.com/c++-faq-lite/
alt.comp.lang.learn.c-c++ ftp://snurse-l.org/pub/acllc-c++/faq

Thu, 03 Feb 2005 08:15:03 GMT
Complete newbie, trouble with unsigned ints.
O.K. I get what you're all saying, but how do I simply return positive
numbers when a user enters negative numbers, i.e. when -10 is entered,
10 is printed?
Quote:

> > Why doesn't this code return the absolute value of -10?

> > #include <stdio.h>

> > int main()
> > {   unsigned pos;

> >     printf("Enter examination mark: ");
> >     scanf("%u", &pos);
> >     printf("Exam mark entered was: %u", pos);
> > }

> > I thought the whole purpose of unsigned ints was to return positive
> > values only, or am I wrong?

> > BTW If I enter -10, I get 4292967286???

> (-10u) equals (UINT_MAX + 1 - 10)

> --
>  pete

Thu, 03 Feb 2005 09:19:50 GMT
Complete newbie, trouble with unsigned ints.

Quote:

> O.K. I get what you're all saying, but how do I simply return positive
> numbers when a user enters negative numbers, i.e. when -10 is entered,
> 10 is printed?

> > > Why doesn't this code return the absolute value of -10?

> > > #include <stdio.h>

> > > int main()
> > > {   unsigned pos;

> > >     printf("Enter examination mark: ");
> > >     scanf("%u", &pos);
> > >     printf("Exam mark entered was: %u", pos);

A program's last output to a stream (stdout in this case)
should be newline terminated for portability reasons.
main() should return an int.

Quote:
> > > }

> > > I thought the whole purpose of unsigned ints
> > > was to return positive values only, or am I wrong?

Converting signed values to positive values of the same magnitude
isn't one of the uses of unsigned int.

#include <stdio.h>
#include <limits.h>

int main(void)
{
unsigned pos;

printf("Enter examination mark: ");
scanf("%u", &pos);
if (pos > INT_MAX) {
pos = 0 - pos;
}
printf("Exam mark entered was: %u\n", pos);
return 0;

Quote:
}

--
pete

Thu, 03 Feb 2005 12:46:23 GMT
Complete newbie, trouble with unsigned ints.

Quote:

> O.K. I get what you're all saying, but how do I simply return positive
> numbers when a user enters negative numbers, i.e. when -10 is entered,
> 10 is printed?

Simply accept the number as an integer, using int rather than unsigned
int, and %d rather than %u. Then call abs(), which is in <stdlib.h>

(I already told you this elsethread - did it not show up on your
server?)

<snip>

--

"Usenet is a strange place." - Dennis M Ritchie, 29 July 1999.
C FAQ: http://www.eskimo.com/~scs/C-faq/top.html
K&R answers, C books, etc: http://users.powernet.co.uk/eton

Thu, 03 Feb 2005 16:44:06 GMT
Complete newbie, trouble with unsigned ints.

Jack Klein a crit:

Quote:
> On Sat, 17 Aug 2002 14:47:32 -0400, Alexandre Jasmin

>>So the standard is really that strict. I tought this was system
>>dependent. Anyway the binary representation of negatives is alway the
>>same for evrery modern computers.

> I assume that you can provide documentation from EVERY MODERN COMPUTER
> to back up this assertion?

Okay. I'll say most of them. ;-)

Fri, 04 Feb 2005 01:06:24 GMT
Complete newbie, trouble with unsigned ints.
Cool, thanks Richard.

PS Ignore my last post.

Quote:

> > Why doesn't this code return the absolute value of -10?

> > #include <stdio.h>

> > int main()
> > {   unsigned pos;

> >     printf("Enter examination mark: ");
> >     scanf("%u", &pos);
> >     printf("Exam mark entered was: %u", pos);
> > }

> > I thought the whole purpose of unsigned ints was to return positive
> > values only, or am I wrong?

> You're right, but not in the way you expected. :-)

> > BTW If I enter -10, I get 4292967286???

> When you assign to an unsigned int, your value is "reduced" modulo
> the-largest-number-that-can-fit-in-it-plus-one.

> For the sake of illustration, let's pretend we're dealing with a 3-bit
> unsigned type whose maximum value is 7. We can think of this type as a
> clock:

>        0
>     7     1
>    6       2
>     5     3
>        4

> (I have no wish to draw a clock with over 4,000,000,000 numerals!)

> The clock has 8 numerals, so we are dealing with "modulo 8 arithmetic".
> This can also be expressed as "modulo
> the-largest-representable-number-plus-one arithmetic", of course.

> Okay, let's do some arithmetic with it.

> 3 + 2 is easy. Start at 3, count 2 places clockwise, and we get 5.
> Intuitive. Good.

> 3 + 5 is just as easy, but not as intuitive. Start at 3, count 5 places
> clockwise, and we come to 0. So, in unsigned-int-with-only-three-bits
> arithmetic, 3 + 5 is 0. Put another way, 3 + 5 = 0 (modulo 8).

> Now let's try some negative numbers. What is 1 - 2? You might expect it
> to be -1. Okay, let's find out; start on 1, count two places
> ANTI-clockwise, and you get 7. Note that 7 is not the absolute value of
> -1!!

> Let's try another one: 0 - 10. Start on 0, count ANTI-clockwise 10
> places: your counting will hit 7 6 5 4 3 2 1 0 7 6 in that order. So -10
> modulo 8 is 6. Not necessarily what you were expecting, but I think you
> can see now how it works.

> Now let's fix your problem:

> To allow the user to enter a minus sign which you then ignore, you can
> use ordinary signed ints, and the abs() function, which is prototyped in
> <stdlib.h>

> --

> "Usenet is a strange place." - Dennis M Ritchie, 29 July 1999.
> C FAQ: http://www.eskimo.com/~scs/C-faq/top.html
> K&R answers, C books, etc: http://users.powernet.co.uk/eton

Fri, 04 Feb 2005 14:56:02 GMT

 Page 1 of 2 [ 22 post ] Go to page: [1] [2]

Relevant Pages