int x = <value>;
int y = (int)((unsigned)x);
The value of y is the same of x for any starting value and C
implementation?
unsigned int x = <value>;
unsigned int y = (unsigned)((int)x);
And in this case?
In other words, is there a risk to loose any value switching from
signed to unsigned and viceversa representation of integers?
|
|
0
|
|
|
|
Reply
|
pozz
|
3/18/2011 10:06:26 AM |
|
pozz <pozzugno@gmail.com> writes:
> int x = <value>;
> int y = (int)((unsigned)x);
>
> The value of y is the same of x for any starting value and C
> implementation?
>
> unsigned int x = <value>;
> unsigned int y = (unsigned)((int)x);
>
> And in this case?
Neither case is safe. Both can involve an out-of-range conversion from
unsigned to int. This is something that you might choose to live with.
In most cases the conversion is implementation defined[1] and will be
defined to do the "obvious" thing.
You can avoid a conversion by "type punning" using either a union or a
pointer conversion:
unsigned u = /* ... */;
int s = *(int *)&u;
This swaps the problem to one of representations. Rather than relying
on the conversion of an out of range value you reply on there being no
unsigned int bit patterns that are not valid signed int representations.
I don't know of any implementations where this is a problem but it is
permitted (by 6.2.6.2 paragraph 2).
As I've alread posted, you can get round both issues if you really need
to.
<snip>
[1] The C standard includes permission to raise a signal but this is not
often done as far as I know.
--
Ben.
|
|
0
|
|
|
|
Reply
|
Ben
|
3/18/2011 11:46:01 AM
|
|
pozz wrote:
>
> int x = <value>;
> int y = (int)((unsigned)x);
>
> The value of y is the same of x for any starting value and C
> implementation?
If <value> is (-1),
then the value of (y) is equal to (int)UINT_MAX.
The value of UINT_MAX is implementation defined.
The value of (int)UINT_MAX may
again be implementation defined
depending on whether UINT_MAX is greater than INT_MAX.
Whether or not UINT_MAX is greater than INT_MAX,
is implementation defined.
--
pete
|
|
0
|
|
|
|
Reply
|
pete
|
3/18/2011 11:57:00 AM
|
|
On 3/18/2011 6:06 AM, pozz wrote:
> int x =<value>;
> int y = (int)((unsigned)x);
>
> The value of y is the same of x for any starting value and C
> implementation?
No. Suppose x is negative. Since an unsigned value cannot be
negative, the (unsigned)x conversion produces a different value
UINT_MAX+x+1. This value is quite likely to be larger than INT_MAX,
so converting it to plain int again produces an implementation-defined
result or raises an implementation-defined signal.
On most C implementations the "implementation-defined result"
turns out to be x, but that's not guaranteed by the language and
can't be counted on for "any" C implementation.
> unsigned int x =<value>;
> unsigned int y = (unsigned)((int)x);
>
> And in this case?
Similar problem: If the value of x is greater than INT_MAX,
converting that value to int is problematic.
> In other words, is there a risk to loose any value switching from
> signed to unsigned and viceversa representation of integers?
Yes. (By the way, "vice versa" is a two-word phrase. Also,
"loose" is a perfectly good verb, but it doesn't mean "lose.")
--
Eric Sosman
esosman@ieee-dot-org.invalid
|
|
0
|
|
|
|
Reply
|
Eric
|
3/18/2011 12:34:30 PM
|
|
On 18 Mar, 12:46, Ben Bacarisse <ben.use...@bsb.me.uk> wrote:
> Neither case is safe. =A0Both can involve an out-of-range conversion from
> unsigned to int.
Hmm..., and what happens with printf, for example:
unsigned int x =3D UINT_MAX;
printf ("x=3D%u\n", x);
Is x converted to int (signed) when it is pushed onto the stack as an
argument for printf? Or maybe it is untouched onto the stack when the
parameter is one of the variable arguments (as happens in printf)?
|
|
0
|
|
|
|
Reply
|
pozz
|
3/18/2011 1:38:52 PM
|
|
On 18 Mar, 13:34, Eric Sosman <esos...@ieee-dot-org.invalid> wrote:
> > In other words, is there a risk to loose any value switching from
> > signed to unsigned and viceversa representation of integers?
>
> =A0 =A0 =A0Yes. =A0(By the way, "vice versa" is a two-word phrase. =A0Als=
o,
> "loose" is a perfectly good verb, but it doesn't mean "lose.")
I'm sorry, I don't know C language as English languange :-)
|
|
0
|
|
|
|
Reply
|
pozz
|
3/18/2011 1:55:27 PM
|
|
pozz <pozzugno@gmail.com> writes:
> On 18 Mar, 12:46, Ben Bacarisse <ben.use...@bsb.me.uk> wrote:
>> Neither case is safe. Both can involve an out-of-range conversion from
>> unsigned to int.
>
> Hmm..., and what happens with printf, for example:
> unsigned int x = UINT_MAX;
> printf ("x=%u\n", x);
>
> Is x converted to int (signed) when it is pushed onto the stack as an
> argument for printf? Or maybe it is untouched onto the stack when the
> parameter is one of the variable arguments (as happens in printf)?
No, you are passing an unsigned int not an it. The default argument
promotions don't affect unsigned int.
--
Ben.
|
|
0
|
|
|
|
Reply
|
Ben
|
3/18/2011 3:08:05 PM
|
|
pozz <pozzugno@gmail.com> writes:
> On 18 Mar, 12:46, Ben Bacarisse <ben.use...@bsb.me.uk> wrote:
>> Neither case is safe. Both can involve an out-of-range conversion from
>> unsigned to int.
>
> Hmm..., and what happens with printf, for example:
> unsigned int x = UINT_MAX;
> printf ("x=%u\n", x);
>
> Is x converted to int (signed) when it is pushed onto the stack as an
> argument for printf? Or maybe it is untouched onto the stack when the
> parameter is one of the variable arguments (as happens in printf)?
No, there is no conversion and no problem. The value of x is passed
as an argument to printf (this probably involves pushing it onto the
stack in most implementations, but the mechanism is irrelevant).
The "%u" tells printf to expect an unsigned argument -- which is
exactly what you gave it. There's no int in sight (other than
the value returned by printf).
If you had used a "%d" format rather than "%u", then the behavior
would be undefined. There would still be no *conversion*; instead,
printf would most likely try to interpret the passed unsigned
int value as if it were of type int. The behavior is likely
to be what you'd expect, but the standard doesn't guarantee it.
(There's a special-case guarantee for the case where the value is
within the range of both types, but that doesn't apply here, since
UINT_MAX is outside the range of int.)
--
Keith Thompson (The_Other_Keith) kst-u@mib.org <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"
|
|
0
|
|
|
|
Reply
|
Keith
|
3/18/2011 3:44:20 PM
|
|
On Mar 18, 7:06=A0am, pozz <pozzu...@gmail.com> wrote:
> int x =3D <value>;
> int y =3D (int)((unsigned)x);
>
> The value of y is the same of x for any starting value and C
> implementation?
>
> unsigned int x =3D <value>;
> unsigned int y =3D (unsigned)((int)x);
>
> And in this case?
>
> In other words, is there a risk to loose any value switching from
> signed to unsigned and viceversa representation of integers?
No. There is no risk. Unsigned and signed integers are the same: they
only differ in how the sign bit is interpreted. y will be exactly x,
ALWAYS. If y was signed, on the other hand, the value could be
different (if and only if it was interpreted as negative, i.e. the
sign bit was set), but the binary content would be rigorously the
same. Even in the case that y were signed, (unsigned)y would be
exactly x. That's because since the binary content is not modified, a
conversion that in the end converts back to the original type will
mean exatcly the same thing.
|
|
0
|
|
|
|
Reply
|
puppi
|
3/20/2011 1:48:19 AM
|
|
puppi <fabricio.puppi@gmail.com> writes:
> On Mar 18, 7:06 am, pozz <pozzu...@gmail.com> wrote:
>> int x = <value>;
>> int y = (int)((unsigned)x);
>>
>> The value of y is the same of x for any starting value and C
>> implementation?
>>
>> unsigned int x = <value>;
>> unsigned int y = (unsigned)((int)x);
>>
>> And in this case?
>>
>> In other words, is there a risk to loose any value switching from
>> signed to unsigned and viceversa representation of integers?
>
> No. There is no risk. Unsigned and signed integers are the same: they
> only differ in how the sign bit is interpreted. y will be exactly x,
> ALWAYS. If y was signed, on the other hand, the value could be
> different (if and only if it was interpreted as negative, i.e. the
> sign bit was set), but the binary content would be rigorously the
> same. Even in the case that y were signed, (unsigned)y would be
> exactly x. That's because since the binary content is not modified, a
> conversion that in the end converts back to the original type will
> mean exatcly the same thing.
What you say is true for many (most) implementations, but it's not
at all guaranteed by the language.
Integer types can have padding bits and/or trap representations.
signed and unsigned int, for example, might not necessarily be
able to represent the same number of values; (signed) int might
have two different representations for zero.
--
Keith Thompson (The_Other_Keith) kst-u@mib.org <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"
|
|
0
|
|
|
|
Reply
|
Keith
|
3/20/2011 2:14:26 AM
|
|
On Mar 19, 11:14=A0pm, Keith Thompson <ks...@mib.org> wrote:
> puppi <fabricio.pu...@gmail.com> writes:
> > On Mar 18, 7:06=A0am, pozz <pozzu...@gmail.com> wrote:
> >> int x =3D <value>;
> >> int y =3D (int)((unsigned)x);
>
> >> The value of y is the same of x for any starting value and C
> >> implementation?
>
> >> unsigned int x =3D <value>;
> >> unsigned int y =3D (unsigned)((int)x);
>
> >> And in this case?
>
> >> In other words, is there a risk to loose any value switching from
> >> signed to unsigned and viceversa representation of integers?
>
> > No. There is no risk. Unsigned and signed integers are the same: they
> > only differ in how the sign bit is interpreted. y will be exactly x,
> > ALWAYS. If y was signed, on the other hand, the value could be
> > different (if and only if it was interpreted as negative, i.e. the
> > sign bit was set), but the binary content would be rigorously the
> > same. Even in the case that y were signed, (unsigned)y would be
> > exactly x. That's because since the binary content is not modified, a
> > conversion that in the end converts back to the original type will
> > mean exatcly the same thing.
>
> What you say is true for many (most) implementations, but it's not
> at all guaranteed by the language.
>
> Integer types can have padding bits and/or trap representations.
> signed and unsigned int, for example, might not necessarily be
> able to represent the same number of values; (signed) int might
> have two different representations for zero.
>
> --
> Keith Thompson (The_Other_Keith) ks...@mib.org =A0<http://www.ghoti.net/~=
kst>
> Nokia
> "We must do something. =A0This is something. =A0Therefore, we must do thi=
s."
> =A0 =A0 -- Antony Jay and Jonathan Lynn, "Yes Minister"
You're correct, of course. I was assuming that signed integers were
represented in two complement's form. Is there any (major) current
implementation that disagrees with that?
|
|
0
|
|
|
|
Reply
|
puppi
|
3/20/2011 5:39:55 AM
|
|
puppi <fabricio.puppi@gmail.com> writes:
> On Mar 19, 11:14 pm, Keith Thompson <ks...@mib.org> wrote:
[...]
>> What you say is true for many (most) implementations, but it's not
>> at all guaranteed by the language.
>>
>> Integer types can have padding bits and/or trap representations.
>> signed and unsigned int, for example, might not necessarily be
>> able to represent the same number of values; (signed) int might
>> have two different representations for zero.
>
> You're correct, of course. I was assuming that signed integers were
> represented in two complement's form.
You were also (implicitly) assuming that the most negative
representable value isn't treated as a trap representation, and
that unsigned-to-signed conversion for values exceeding INT_MAX
works as expected (it's implementation-defined).
> Is there any (majorm) current
> implementation that disagrees with that?
I don't believe there are any conforming *hosted* implementations
that don't meet those assumptions. There tends to be more variation
among freestanding implementations, but I don't know the details.
--
Keith Thompson (The_Other_Keith) kst-u@mib.org <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"
|
|
0
|
|
|
|
Reply
|
Keith
|
3/20/2011 4:01:26 PM
|
|
Ben Bacarisse <ben.use...@bsb.me.uk> wrote:
> pozz <pozzu...@gmail.com> writes:
<snip>
> > unsigned int x =3D <value>;
> > unsigned int y =3D (unsigned)((int)x);
>
> Neither case is safe. =A0Both can involve an out-of-range
> conversion from unsigned to int.
More subtle is the case...
unsigned short x =3D USHRT_MAX;
unsigned short y =3D ++x;
The second initialisor expression can overflow if USHRT_MAX <=3D
INT_MAX. Since ++x is just shorthand for x =3D x + 1, the sub-
expression x + 1 can overflow if x is promoted to int and not
unsigned int. That can be true even if USHRT_MAX =3D=3D UINT_MAX in
the case where UINT_MAX =3D=3D INT_MAX.
--
Peter
|
|
0
|
|
|
|
Reply
|
Peter
|
3/20/2011 10:16:50 PM
|
|
Peter Nilsson <airia@acay.com.au> writes:
> Ben Bacarisse <ben.use...@bsb.me.uk> wrote:
>> pozz <pozzu...@gmail.com> writes:
> <snip>
>> > unsigned int x = <value>;
>> > unsigned int y = (unsigned)((int)x);
>>
>> Neither case is safe. Both can involve an out-of-range
>> conversion from unsigned to int.
>
> More subtle is the case...
>
> unsigned short x = USHRT_MAX;
> unsigned short y = ++x;
>
> The second initialisor expression can overflow if USHRT_MAX <=
> INT_MAX. [snip elaboration]
Presumably you mean ++x can overflow if USHRT_MAX == INT_MAX.
There is no overflow if USHRT_MAX < INT_MAX.
|
|
0
|
|
|
|
Reply
|
Tim
|
3/20/2011 11:32:42 PM
|
|
|
13 Replies
226 Views
(page loaded in 0.178 seconds)
Similiar Articles: LSA Disk Sector Read - using int 13h ah 42 (extended read) - comp ...... void LBASectorRead(void *buffer, unsigned ... si, disk_pack; mov ah, 42h; int ... You'll need to look for a compiler specific option, something like "#pragma pack ... signed/unsigned as fundamental types - comp.lang.c++.moderated ...The standard defines signed int, unsigned int, etc. as fundamental types. I was asking myself why they aren't defined as compound types. defining the... How to send binary or hex data in Socket using C ? - comp.unix ...And I really loose some touch here.. How can I send a ... To send these bytes, you only need to use write(2), something like: void write_buffer(unsigned char* bytes,int ... error LNK2020: Unresolved token - comp.lang.c===== If you need more information, you'll need to ask in a ... int or unsigned int. Signed int is a synonym for int. but in fact something declared as unsigned int ... Casting between 64bit and 32bit - comp.unix.programmerThe problem isn't typecast warning (you'll ... it seems 32 bit DWORD's are defined as unsigned int ... The disadvantages is that you loose type-safety. void f1(int flag ... Large numbers, floating point number questions - comp.lang.c ...... return acc; } int main(int argc, char **argv) { unsigned long s ... You'll need an `unsigned long' of about 525 bits or ... net/~kst> Nokia "We must do something ... portability of integral types in C++ on UNIX - comp.unix ...... string.h> #define SIGNED 1 #define UNSIGNED 0 char * getMatchingType(int ... I'll discuss with my group. We will be ... within integral types, or which uses something ... integer overflow in atoi - comp.lang.c... and str is "11111111111111111" you'll conclude ... shorter than a "stringified" version of INT_MAX is something I ... 2^8 =3D 256 (UNSIGNED_INT_MAX =3D 255, bitlength ... unsigned long -> ascii conversion - comp.lang.asm.x86I'll let you work it out. ; convert ... I.e. something like my full 32-bit unsigned to ascii conversion which I ... Unsigned long int to ASCII conversion - failed ... Signed shift of 32-bit int using 16-bit instructions? - comp.lang ...Something like this might work: shl ax,1 rcl dx,1 pushf ... now have an overflow problem, so I'll be >trying to ... unsigned int to ABGR float values - comp.graphics.api.opengl ... 128 bit integer - comp.lang.cRepeat the above replacing "int" with "uint" for unsigned types. ... with IPv6 as I definitely should be, but I'll ... be convenient to do > a bitwise mask on something ... SuperKISS for 32- and 64-bit RNGs in both C and Fortran. - comp ...> ----- <snip> > int main() > {int i; unsigned long long x; > for ... uses KISS in operations, like: z =3D KISS % Something ... I'll admit to being a small, ignorant dinosaur ... External variables - comp.lang.asm.x86... to use this data, so I did: ..... extern unsigned int *my ... That this is an int is something you have to make sure of ... do extern <some data type> *var[8]; and I'll ... c99 uint32_t (etc.) corresponding portable printf format ...... fprintf specifiers, just the existing l, ll ... n .CJacehknorstu";int putchar(int);int main(void){unsigned long b ... This is something. Therefore, we must do this ... Compile time testing for "type equality"? - comp.lang.c++ ...... but the situation where it happens is that I have something as follows: > > template <class T, class I = unsigned int ... use the same control block, so they'll compare equal ... Data Type Ranges (C++)Type Name Bytes Other Names Range of Values int. 4. signed –2,147,483,648 to 2,147,483,647. unsigned int. 4. unsigned coding style - Should you always use 'int' for numbers in C, even ...I always use unsigned int for values that should never be negative. But today I noticed this situation in my code: void CreateRequestHeader( unsigned bitsAvailable ... 7/17/2012 8:19:24 AM
|