Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > From unsigned int to int and back

Reply
Thread Tools

From unsigned int to int and back

 
 
Philliam Auriemma
Guest
Posts: n/a
 
      02-13-2010
I am writing a program and I have a function that returns an unsigned
int, but I need to turn it into an int. Can I just do that by doing
like

unsigned int a = 1;
b = (int)a;

As long as a is not too large to fit inside a regular int? Or will
this lose some data or something?
Also when getting an int, can I just do the opposite of the above:

c = (unsigned int)b;

?
 
Reply With Quote
 
 
 
 
Robert Fendt
Guest
Posts: n/a
 
      02-13-2010
And thus spake Philliam Auriemma <(E-Mail Removed)>
Fri, 12 Feb 2010 18:19:20 -0800 (PST):

> As long as a is not too large to fit inside a regular int? Or will
> this lose some data or something?


Note: actually your question is more C than C++. To add a C++
specific note, consider using static_cast<>, reinterpret_cast<>
and the like instead of the 'automagic' C cast. The C++ form
allows you to specify exactly what you want to achieve, thus
enabling better diagnostics from the compiler.

Casting if the target is large enough for the number will always
work. If it is not, it will still 'work', but the result is
unspecified. I.e. this works without problem (on a compiler that
supports long long, as do at least GCC and VC++):

unsigned long long val1 = 10;
char val2 = static_cast<char>(val1);

but the result of this is another matter:

unsigned short x = 16384;
unsigned char y = static_cast<unsigned char>(x);

I think the standard specifies for integer casts that the number
is 'capped' on a bit level. Usually, the above example will thus
yield y==0, since 16384==100000000000000b;

However just casting from signed to unsigned is (IIRC)
guaranteed to work even without loss of data, meaning that for
any int 'x' the following holds true:

static_cast<int>(static_cast<unsigned>(x)) == x

This even works if for example x is negative. In that case
though there's a another caveat: the semantics of interpreting a
negative number as unsigned are AFAIK implementation-defined.
The sizes of most base types (and AFAIK even the exact bit
representation format of a neg. number) are not enforced by the
standard (it only specifies constraints on value ranges), so one
has to be extra-careful.

Regards,
Robert

 
Reply With Quote
 
 
 
 
James Kanze
Guest
Posts: n/a
 
      02-13-2010
On 13 Feb, 02:19, Philliam Auriemma <(E-Mail Removed)> wrote:
> I am writing a program and I have a function that returns an
> unsigned int, but I need to turn it into an int. Can I just do
> that by doing like


> unsigned int a = 1;
> b = (int)a;


> As long as a is not too large to fit inside a regular int?


If the value can be represented in an int (i.e. it is less than
or equal to INT_MAX), the conversion is not only well formed,
but fully defined. If the value is in the range
INT_MAX+1...UINT_MAX, the results of the conversion are
implementation defined, and may result in an implementation
defined signal, but in practice, on most machines today,
you'll end up with a negative number that, when converted back
to an unsigned, will result in the same value.

> Or will this lose some data or something?
> Also when getting an int, can I just do the opposite of the above:


> c = (unsigned int)b;


> ?


That's well defined. If the value is negative, the result is
UINT_MAX+1 + b. Basically, the same bit pattern on 2's
complement machines (which are most of those you're likely to
see---as far as I know, Unisys mainframes are the only non 2's
complement machines being sold today).

--
James Kanze
 
Reply With Quote
 
James Kanze
Guest
Posts: n/a
 
      02-13-2010
On 13 Feb, 07:59, Robert Fendt <(E-Mail Removed)> wrote:
> And thus spake Philliam Auriemma <(E-Mail Removed)>
> Fri, 12 Feb 2010 18:19:20 -0800 (PST):


> > As long as a is not too large to fit inside a regular int?
> > Or will this lose some data or something?


> Note: actually your question is more C than C++.


What makes you say that? The code is fully legal C++, and the
formal requirements for it are slightly different in C and in
C++ (although in practice, almost everyone does something that
is legal in both).

> To add a C++ specific note, consider using static_cast<>,
> reinterpret_cast<>


The only new-style cast which would be legal here would be
static_cast, and most people I know continue to prefer either
the old style casts or function style casts when neither
pointers nor references are involved.

> Casting if the target is large enough for the number will
> always work.


For some definition of "work" and "large enough". If floating
point is involved, the rules obviously change.

> If it is not, it will still 'work', but the result is
> unspecified. I.e. this works without problem (on a compiler
> that supports long long, as do at least GCC and VC++):


> unsigned long long val1 = 10;
> char val2 = static_cast<char>(val1);


This is guaranteed to work, on all compilers, since 10 can
always be represented in a char.

> but the result of this is another matter:


> unsigned short x = 16384;
> unsigned char y = static_cast<unsigned char>(x);


This is also guaranteed to "work", with strictly defined
semantics.

> I think the standard specifies for integer casts that the
> number is 'capped' on a bit level. Usually, the above example
> will thus yield y==0, since 16384==100000000000000b;


The results of the conversion are the initial value modulo 2^n,
where n is the number of significant bits in a char (at least
.

> However just casting from signed to unsigned is (IIRC)
> guaranteed to work even without loss of data,


For some meaning of "loss of data". There's no guarantee of a
round trip.

> meaning that for any int 'x' the following holds true:


> static_cast<int>(static_cast<unsigned>(x)) == x


> This even works if for example x is negative.


There are machines where this doesn't hold.

> In that case though there's a another caveat: the semantics of
> interpreting a negative number as unsigned are AFAIK
> implementation-defined.


The semantics of interpreting any type as another type is
undefined behavior, unless a character type is involved.
According to the standard; the standard also implies, in its
language concerning reinterpret_cast, that implementations
should do something reasonable (because otherwise
reinterpret_cast is useless).

--
James Kanze
 
Reply With Quote
 
Philliam Auriemma
Guest
Posts: n/a
 
      02-13-2010
On Feb 13, 4:35*am, James Kanze <(E-Mail Removed)> wrote:
> On 13 Feb, 07:59, Robert Fendt <(E-Mail Removed)> wrote:
>
> > And thus spake Philliam Auriemma <(E-Mail Removed)>
> > Fri, 12 Feb 2010 18:19:20 -0800 (PST):
> > > As long as a is not too large to fit inside a regular int?
> > > Or will this lose some data or something?

> > Note: actually your question is more C than C++.

>
> What makes you say that? *The code is fully legal C++, and the
> formal requirements for it are slightly different in C and in
> C++ (although in practice, almost everyone does something that
> is legal in both).
>
> > To add a C++ specific note, consider using static_cast<>,
> > reinterpret_cast<>

>
> The only new-style cast which would be legal here would be
> static_cast, and most people I know continue to prefer either
> the old style casts or function style casts when neither
> pointers nor references are involved.
>
> > Casting if the target is large enough for the number will
> > always work.

>
> For some definition of "work" and "large enough". *If floating
> point is involved, the rules obviously change.
>
> > If it is not, it will still 'work', but the result is
> > unspecified. I.e. this works without problem (on a compiler
> > that supports long long, as do at least GCC and VC++):
> > unsigned long long val1 = 10;
> > char val2 = static_cast<char>(val1);

>
> This is guaranteed to work, on all compilers, since 10 can
> always be represented in a char.
>
> > but the result of this is another matter:
> > unsigned short x = 16384;
> > unsigned char y = static_cast<unsigned char>(x);

>
> This is also guaranteed to "work", with strictly defined
> semantics.
>
> > I think the standard specifies for integer casts that the
> > number is 'capped' on a bit level. *Usually, the above example
> > will thus yield y==0, since 16384==100000000000000b;

>
> The results of the conversion are the initial value modulo 2^n,
> where n is the number of significant bits in a char (at least
> .
>
> > However just casting from signed to unsigned is (IIRC)
> > guaranteed to work even without loss of data,

>
> For some meaning of "loss of data". *There's no guarantee of a
> round trip.
>
> > meaning that for any int 'x' the following holds true:
> > static_cast<int>(static_cast<unsigned>(x)) == x
> > This even works if for example x is negative.

>
> There are machines where this doesn't hold.
>
> > In that case though there's a another caveat: the semantics of
> > interpreting a negative number as unsigned are AFAIK
> > implementation-defined.

>
> The semantics of interpreting any type as another type is
> undefined behavior, unless a character type is involved.
> According to the standard; the standard also implies, in its
> language concerning reinterpret_cast, that implementations
> should do something reasonable (because otherwise
> reinterpret_cast is useless).
>
> --
> James Kanze


Wow thank you all for the thoughtful and extremely thorough replies.
This makes my life a lot easier.
 
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
int*unsigned int = unsigned? ciccio C++ 2 06-04-2010 01:54 PM
is vec.reserve(unsigned int) better than vec(unsigned int)? er C++ 6 09-14-2007 06:20 AM
comparing unsigned long and unsigned int sridhar C Programming 6 11-03-2004 03:52 AM
unsigned int const does not match const unsigned int Timo Freiberger C++ 3 10-30-2004 07:02 PM



Advertisments