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 ...

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

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 ?

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.

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

> 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.

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.

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

...

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

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* ? ;-)

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

1. unsigned 32 bit large integer multiplication unsigned 64 bit integers random

2. Integral conversion from negative signed to unsigned integer

3. Integer signed/unsigned type conversions

4. Splitting a 32 bit integer into two unsigned 8 bit integers

5. dbExpress conversion Oracle integer Delphi integer

6. converting unsigned integers to signed

7. Do saturating integers solve the "signed vs. unsigned" debate?

8. Lesson 3, Integer Assignments, Signed to Unsigned with Mixed Sizes.

9. Lesson 4, Integer Assignments, Unsigned to Signed with Mixed Sizes.

10. How to handle display 128 bit integer (signed and unsigned)

11. how to transform 64 bit signed integer to unsigned?

12. integer datatype confusion, signed vs unsigned

13. comparison between signed and unsigned integer expressions

14. Modbus real to unsigned integer conversion

15. double-to-unsigned integer conversion bug

10 post • Page:**1** of **1**