conversion of signed integer to unsigned integer

conversion of signed integer to unsigned integer

Post by junky_fell » Sat, 18 Jun 2005 21:26:56


Can anybody please explain this:

[ N869 6.3.1.3 ]

When a value with integer type is converted to another integer type
other than _Bool,
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.


Thanx ...
 
 
 

conversion of signed integer to unsigned integer

Post by Eric Sosma » Sat, 18 Jun 2005 21:55:17


unsigned short us; /* assume USHRT_MAX == 65535 */
us = -1000000;

The variable is unsigned, and not capable of expressing a
negative value. The assignment must set it to a non-negative
value, and 6.3.1.3 describes how that value is computed:

-1000000
+65536 (USHRT_MAX+1)
========
-934464
+65536
========
-868928
:
:
========
-16960
+65536
========
48576 (final answer, Regis)

Various computational shortcuts are available; all those
additions need not actually be peformed to get to the answer.

--
Eric Sosman
XXXX@XXXXX.COM

 
 
 

conversion of signed integer to unsigned integer

Post by junky_fell » Sat, 18 Jun 2005 22:35:09


Consider,
signed char sc = -4; /* binary = 11111100 */
unsigned char uc = sc;

Now, if I print the value of sc it is 252 (binary 11111100).

So, if you see no conversion has been done. The bit values in
"uc" are exactly the same as in "sc".

Then, whats the need of performing so many additions/subtractions ?
 
 
 

conversion of signed integer to unsigned integer

Post by Jean-Claud » Sat, 18 Jun 2005 22:49:51


Great confusion between bit pattern and actual value, here.
First, 252 = -4 + 256, needed to get a valid unsigned char.
Second, not all machines are 2-complement, though many are
nowadays.

As Eric said, there are computational shortcuts, and you
should note they depend on the machine (hence, on the
implementation of the standard). It's pure coincidence
if a signed char and an unsigned char have actually the same
representation for "s" and "256+s" respectively.
 
 
 

conversion of signed integer to unsigned integer

Post by Jean-Claud » Sat, 18 Jun 2005 23:02:27


Le 17/06/2005 15:49, dans BED8A19F.50FE% XXXX@XXXXX.COM ,
Jean-Claude Arbaut < XXXX@XXXXX.COM > a rit?


Just for reference:

ISO 9899-1999, section 6.2.6.2#2 p39
 
 
 

conversion of signed integer to unsigned integer

Post by Me » Sun, 19 Jun 2005 01:03:53

> Can anybody please explain this:

It's basically describing a mod operation. Lets say you want to convert
any random signed integer to an unsigned int, a table of those values
looks like:

...
UINT_MAX+2 1
UINT_MAX+1 0
UINT_MAX UINT_MAX
UINT_MAX-1 UINT_MAX-1
UINT_MAX-2 UINT_MAX-2
...
2 2
1 1
0 0
-1 UINT_MAX
-2 UINT_MAX-1
...
-UINT_MAX+1 2
-UINT_MAX 1
-UINT_MAX-1 0
-UINT_MAX-2 UINT_MAX
-UINT_MAX-3 UINT_MAX-1
...

Where the left side is the signed integer value and the right side is
the resulting value when converted to unsigned int. I'm sure you can
figure it out from there.
 
 
 

conversion of signed integer to unsigned integer

Post by Mac » Sun, 19 Jun 2005 01:20:16


junky,

Eric is pretty sharp. He dumbed down his answer a bit because he was
afraid of confusing you. Your first post made it look like you were prone
to confusion. Your second post has not changed that appearance.

But now you are coming back like a smart-alec. ;-)

Even so, nothing in Eric's post is incorrect, as far as I can see, and
nothing in your followup contradicts anything in Eric's post.

He specifically said that the additions and/or subtractions need not
actually be performed to get the answer.

In the case of typical architectures, converting from unsigned to signed
of the same size may well be a no-op. The conversion really just means
that the compiler will change how it thinks of the bit pattern, not the
bit-pattern itself. As it turns out, this behavior satisfies the
mathematical rules laid out in the standard. This is probably not a
coincidence. I believe the intent of the rule was to force any non two's
complement architectures to emulate two's complement behavior. This is
convenient for programmers.

Even in the cases where a conversion from signed to unsigned involves
types of different sizes, typical architectures will have minimal work to
do to perform the conversion as specified in the standard. Non-typical
architectures, if there really are any, might have to do some arithmetic.

--Mac
 
 
 

conversion of signed integer to unsigned integer

Post by Lawrence K » Sun, 19 Jun 2005 01:59:55


...


That is the representation on your implementation, it may be something
else on another implementation.


Yes it has. You had a value of -4, now you have a value of 252. A very
real conversion has happened that has produced a different value.


That's a happy coincidence, well not entirely a coincidence. The
conversion rules are designed to be efficiently implementable on common
architectures as well as being useful.

The underlying representation is not important, the result of the
conversion is defined on VALUES. You stared with a value and following the
conversion rules you added (UCHAR_MAX+1) in this case 256 to produce a
result of 252. You didn't need to know anything about the underlying
representation to determine that. On a 1's complement implementation -4
would be represented in 8 bits as 11111011, but uc = sc would still
produce the result 252 because the conversion is defined in terms of
value. On such systems the implementation must change the representation
to produce the correct result. That's the price you pay for portability
and consistent results.


The additions/subtractions are just a means in the standard to specify
what the correct result should be. In practice a compiler would not
perform lots of additions or subtractions to actually calculate the result.

As you've noted in a lot of cases it doesn't have to do anything at all
except reinterpret a bit pattern according to a new type.

Lawrence
 
 
 

conversion of signed integer to unsigned integer

Post by Jean-Claud » Sun, 19 Jun 2005 06:42:16


Le 17/06/2005 23:03, dans XXXX@XXXXX.COM , Mac
< XXXX@XXXXX.COM > a rit?



I didn't understand that way the first time. Your guess is quite
reasonable.


That's what made me understand :-)

Yes, but we were interested in the conversion -4 -> 252, so *negative*
signed chars. In case you convert a positive signed char to an unsigned
char, section 6.3.1.3#1 says the value shall not change if it is
representable. Since signed/unsigned types have the same size by 6.2.5#6,
I assume a positive signed char is always representable as an unsigned
char. Hence the *value* won't change. Now for the representation:
section 6.2.6.2#2 says there is sign correction only when the sign bit
is one, this means a positive signed char always have sign bit 0,
hence there is *nothing* to do during conversion. I hope I got right
in my interpretation of the standard. Otherwise, a guru will soon yell
at me, _again_ ;-)



Well I do too, but saying so one is often accused of thinking
there are only wintels in the world :-)


You say that to ME !!! Well, if you read my recent posts, you'll
see I am not advocating enforcing the standard too strongly ;-)
I am merely discovering the standard, and I must admit it's a shame
I have programmed in C for years without knowing a line from it.
It's arid at first glance, but it deserves deeper reading.
Wow, I said *that* ? ;-)
 
 
 

conversion of signed integer to unsigned integer

Post by pete » Sun, 19 Jun 2005 10:59:17


I think you mean uc


That doesn't matter.
252 isn't -4.
A conversion has been done.


-4 could also be either 11111011 or 10000100

The subtractions are a procedure that produces
the correct result regardless of representation.

When the represention is known, then easier ways can be used,
like interpreting
((unsigned char)sc)
as
(*(unsigned char *)&sc),
as your two's complement system may.

--
pete