Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C Programming > Signed <-> Unsigned conversions.

Reply
Thread Tools

Signed <-> Unsigned conversions.

 
 
Charles Sullivan
Guest
Posts: n/a
 
      08-26-2010

Is there a C standard for how conversions between signed and unsigned
variables of the same size are implemented. E.g., if I have:

signed int s1, s2;
unsigned int u1;

s1 = -100;
u1 = s1;
s2 = u1;

printf("s2 = %d\n", s2);

With my (gcc) compiler, s2 has the same value (-100) as s1, but I'm
wondering if that's a C standard.

Thanks for your help.

 
Reply With Quote
 
 
 
 
John Kelly
Guest
Posts: n/a
 
      08-26-2010
On Thu, 26 Aug 2010 17:08:19 GMT, Charles Sullivan
<(E-Mail Removed)> wrote:

>
>Is there a C standard for how conversions between signed and unsigned
>variables of the same size are implemented. E.g., if I have:
>
> signed int s1, s2;
> unsigned int u1;
>
> s1 = -100;
> u1 = s1;


at this point u1 = 4294967196


> s2 = u1;


which cannot be represented in s2. Now if you believe in standards, C99
say:


> Otherwise, the new type is signed and the value cannot be
> represented in it; either the result is implementation-defined
> or an implementation-defined signal is raised.


So your program may freak out, or it may give you a reasonable answer,
depending on your compiler "implementation."


> printf("s2 = %d\n", s2);
>
>With my (gcc) compiler, s2 has the same value (-100) as s1, but I'm
>wondering if that's a C standard.
>
>Thanks for your help.


I'm still waiting for someone to point out an implementation that raises
a signal in this case.




--
Web mail, POP3, and SMTP
http://www.beewyz.com/freeaccounts.php

 
Reply With Quote
 
 
 
 
osmium
Guest
Posts: n/a
 
      08-26-2010
"John Kelly" wrote:

> On Thu, 26 Aug 2010 17:08:19 GMT, Charles Sullivan
> <(E-Mail Removed)> wrote:
>
>>
>>Is there a C standard for how conversions between signed and unsigned
>>variables of the same size are implemented. E.g., if I have:
>>
>> signed int s1, s2;
>> unsigned int u1;
>>
>> s1 = -100;
>> u1 = s1;

>
> at this point u1 = 4294967196
>
>
>> s2 = u1;

>
> which cannot be represented in s2. Now if you believe in standards, C99
> say:
>
>
>> Otherwise, the new type is signed and the value cannot be
>> represented in it; either the result is implementation-defined
>> or an implementation-defined signal is raised.


Or that could have been written in English as

"The result is defined by the implementation."

>
> So your program may freak out, or it may give you a reasonable answer,
> depending on your compiler "implementation."
>
>
>> printf("s2 = %d\n", s2);
>>
>>With my (gcc) compiler, s2 has the same value (-100) as s1, but I'm
>>wondering if that's a C standard.
>>
>>Thanks for your help.

>
> I'm still waiting for someone to point out an implementation that raises
> a signal in this case.
>
>
>
>
> --
> Web mail, POP3, and SMTP
> http://www.beewyz.com/freeaccounts.php
>



 
Reply With Quote
 
Keith Thompson
Guest
Posts: n/a
 
      08-26-2010
Charles Sullivan <(E-Mail Removed)> writes:
> Is there a C standard for how conversions between signed and unsigned
> variables of the same size are implemented. E.g., if I have:
>
> signed int s1, s2;
> unsigned int u1;
>
> s1 = -100;
> u1 = s1;
> s2 = u1;
>
> printf("s2 = %d\n", s2);
>
> With my (gcc) compiler, s2 has the same value (-100) as s1, but I'm
> wondering if that's a C standard.


If you want *all* the gory details, grab a copy of the latest
almost-official C standard draft from
<http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1256.pdf>
and read the section on Conversions (6.3).

To summarize:

s1 = -100 assigns an int value to an int object; no conversion
is needed.

u1 = s1 peforms an implicit conversion of the int value -100 from
int to unsigned int. For a value out of range of the unsigned
type, the standard specifies that the conversion is done "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" (this refers to mathematical values, not
to addition or subtraction as it would be done in C). Which is a
somewhat roundabout way of describing the way it typically works on
systems that use a 2's-complement representation for signed integers
(other (rare) systems must do whatever is needed to produce the
same result). So the value stored in u1 is UINT_MAX + 1 - 100.
If UINT_MAX is 65535, u1 is 65436u; if UINT_MAX is 4294967295,
u1 is 4294967196u.

s2 = u1 attempts to convert the unsigned int value UINT_MAX +
1 - 100 from unsigned int to int. Typically this will just
reverse the previous conversion and yield -100, but the standard
doesn't guarantee this; it says that "either the result is
implementation-defined or an implementation-defined signal is
raised". (The permission to raise a signal is new in C99; in C90,
it merely produced an implementation-defined result.)

So the behavior you're seeing is typical, but not guaranteed.

--
Keith Thompson (The_Other_Keith) http://www.velocityreviews.com/forums/(E-Mail Removed) <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
 
Reply With Quote
 
Keith Thompson
Guest
Posts: n/a
 
      08-26-2010
John Kelly <(E-Mail Removed)> writes:
> On Thu, 26 Aug 2010 17:08:19 GMT, Charles Sullivan
> <(E-Mail Removed)> wrote:
>
>>
>>Is there a C standard for how conversions between signed and unsigned
>>variables of the same size are implemented. E.g., if I have:
>>
>> signed int s1, s2;
>> unsigned int u1;
>>
>> s1 = -100;
>> u1 = s1;

>
> at this point u1 = 4294967196


Only if UINT_MAX happens to be 4294967295 (which is common but not
universal).


>> s2 = u1;

>
> which cannot be represented in s2. Now if you believe in standards, C99
> say:
>
>
>> Otherwise, the new type is signed and the value cannot be
>> represented in it; either the result is implementation-defined
>> or an implementation-defined signal is raised.


What does C99 say if you don't believe in standards? What on Earth does
"believe in standards" even mean?

[...]
> I'm still waiting for someone to point out an implementation that raises
> a signal in this case.


Why are you waiting for that? The standard permits it; that doesn't
imply that any implementation takes advantage of that permission.
(I know of none that do so.)

--
Keith Thompson (The_Other_Keith) (E-Mail Removed) <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
 
Reply With Quote
 
Keith Thompson
Guest
Posts: n/a
 
      08-26-2010
"osmium" <(E-Mail Removed)> writes:
> "John Kelly" wrote:

[...]
>>> Otherwise, the new type is signed and the value cannot be
>>> represented in it; either the result is implementation-defined
>>> or an implementation-defined signal is raised.

>
> Or that could have been written in English as
>
> "The result is defined by the implementation."


How is that an improvement? How is "the result is
implementation-defined"
not English?

Note that the standard defines the term "implementation-defined"
in 3.4.1.

--
Keith Thompson (The_Other_Keith) (E-Mail Removed) <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
 
Reply With Quote
 
BGB / cr88192
Guest
Posts: n/a
 
      08-26-2010

"Behind China Blue Eyes" <(E-Mail Removed)> wrote in message
news:(E-Mail Removed)...
> In article <7cxdo.23933$(E-Mail Removed)>,
> Charles Sullivan <(E-Mail Removed)> wrote:
>
>> Is there a C standard for how conversions between signed and unsigned
>> variables of the same size are implemented. E.g., if I have:
>>
>> signed int s1, s2;
>> unsigned int u1;
>>
>> s1 = -100;
>> u1 = s1;
>> s2 = u1;

>
> On a typical twos complement machine, it uses the same bits, just labelled
> with
> a signed or unsigned type. That's because the address arithmetic works out
> the
> same if you ignore overflow. Whilst many of these machines can detect
> integer
> overflow, I don't recall any C compilers that signal it. Division produces
> different values signed and unsigned, but not addition and subtraction.
>


it would be extra effort to detect and to signal on many CPU's, and would
reduce performance, so it is generally not worth the bother.

in my case, when I wrote a compiler, I largely ignored the difference
between signed and unsigned types except in cases where it actually matters.
typically, the same CPU instructions are used either way, so it doesn't
matter too much.

a little more effort though is preserving the correct behavior of smaller
integer types when typically using full-width registers and operations,
since a lot of code will by unhappy if a calculation which exploits overflow
behavior just happens to perform the calculation with a wider-than-expected
value range.

example:
unsigned char a, b;
int c;

a=254; b=3;
c=a+b;

c should be 1, rather than 257.

it may seem trivial, but code can actually misbehave or break due to these
sorts of issues (as some naively written hash function produces a different
value, ...).

as well as finding the least-cost way of pulling this off:
for example, consider a byte-addition will preserve the correct behavior,
but maybe only certain registers have a byte-width addition instruction;
otherwise, one may have to use a full-width addition and use a mask or
zero-extend opcode to fix the result (but, this shouldn't always be done, as
maybe this costs an additional clock cycle the prior);
....

but, yeah, it is all this little fiddly crap which makes compiler writing
"fun" (and leads to lots of difficult-to-track-down bugs...).

or such...



 
Reply With Quote
 
osmium
Guest
Posts: n/a
 
      08-26-2010

"Keith Thompson" <(E-Mail Removed)> wrote in message
news:(E-Mail Removed)...
> "osmium" <(E-Mail Removed)> writes:
>> "John Kelly" wrote:

> [...]
>>>> Otherwise, the new type is signed and the value cannot be
>>>> represented in it; either the result is implementation-defined
>>>> or an implementation-defined signal is raised.

>>
>> Or that could have been written in English as
>>
>> "The result is defined by the implementation."

>
> How is that an improvement? How is "the result is
> implementation-defined"
> not English?
>
> Note that the standard defines the term "implementation-defined"
> in 3.4.1.


It is one single thought in a simple sentence. The messing with word
arrangement was just my way of saying it, that was not the point I was
trying to make. Why force the reader to tangle with a compound thought when
a single thought is the only information being conveyed? This is the
convoluted way lawyers talk.

On the tangential thing, "defined by the implementation" does not need to be
defined someplace else in the spec. It is a meaningful thought, all by
it's lonesome.


 
Reply With Quote
 
Keith Thompson
Guest
Posts: n/a
 
      08-26-2010
"BGB / cr88192" <(E-Mail Removed)> writes:
[...]
> it would be extra effort to detect and to signal on many CPU's, and would
> reduce performance, so it is generally not worth the bother.
>
> in my case, when I wrote a compiler, I largely ignored the difference
> between signed and unsigned types except in cases where it actually matters.
> typically, the same CPU instructions are used either way, so it doesn't
> matter too much.


And the rules in the C standard are specifically designed to allow (but
not require) you to do this.

> a little more effort though is preserving the correct behavior of smaller
> integer types when typically using full-width registers and operations,
> since a lot of code will by unhappy if a calculation which exploits overflow
> behavior just happens to perform the calculation with a wider-than-expected
> value range.
>
> example:
> unsigned char a, b;
> int c;
>
> a=254; b=3;
> c=a+b;
>
> c should be 1, rather than 257.


No, c should be 257, and if it isn't you have a bug in your compiler
(assuming it's intended to be a conforming C compiler). C99 6.5.6p4:

If both operands have arithmetic type, the usual arithmetic
conversions are performed on them.

In this case, the "usual arithmetic conversions" (6.3.1. apply the
"integer promotions" (6.3.1.1p2), which promote unsigned char to int
(or, rarely, to unsigned int, but the result is the same either way).

[...]

--
Keith Thompson (The_Other_Keith) (E-Mail Removed) <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
 
Reply With Quote
 
Seebs
Guest
Posts: n/a
 
      08-26-2010
On 2010-08-26, osmium <(E-Mail Removed)> wrote:
> "Keith Thompson" <(E-Mail Removed)> wrote in message
> news:(E-Mail Removed)...
>> "osmium" <(E-Mail Removed)> writes:
>>> "John Kelly" wrote:


>>>>> Otherwise, the new type is signed and the value cannot be
>>>>> represented in it; either the result is implementation-defined
>>>>> or an implementation-defined signal is raised.


>>> Or that could have been written in English as


>>> "The result is defined by the implementation."


> It is one single thought in a simple sentence.


But it screws the reader over.

Most readers will, given only your sentence, not consider "a signal
is raised" to be a possible outcome. The reason for the bifurcation
is that these are two separate outcomes, and the implementation must
document not only which one it picked, but the details of the choice.

But it is important to distinguish between this and a case where you
definitely get a number as a result, but the implementation defines
which one.

-s
--
Copyright 2010, all wrongs reversed. Peter Seebach / (E-Mail Removed)
http://www.seebs.net/log/ <-- lawsuits, religion, and funny pictures
http://en.wikipedia.org/wiki/Fair_Game_(Scientology) <-- get educated!
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
(int) -> (unsigned) -> (int) or (unsigned) -> (int) -> (unsigned):I'll loose something? pozz C Programming 12 03-20-2011 11:32 PM
Convert a signed binary number into a signed one ? Rob1bureau VHDL 1 02-27-2010 12:13 AM
signed(12 downto 0) to signed (8 downto 0) kyrpa83 VHDL 1 10-17-2007 06:58 PM
signed to unsigned Patrick VHDL 1 06-07-2004 01:59 PM
STD_LOGIC_VECTOR vs. UNSIGNED vs. SIGNED Jeremy Pyle VHDL 3 06-28-2003 10:47 PM



Advertisments