Conversion between signed integer and unsigned integer
Asked Answered
H

1

2

If I cast an unsigned integer to a signed integer then cast back, am I guaranteed to get the original value? For example, does this function always return true for any x on any platform according to the C++ standard?

bool f(unsigned int x)
{
    return x == static_cast<unsigned int>(static_cast<int>(x));
}

What about this one?

bool g(int x)
{
    return x == static_cast<int>(static_cast<unsigned int>(x));
}
Hydrogeology answered 26/5, 2016 at 1:57 Comment(15)
@sleeptightpupper I've made a mistake in my code. Sorry for the misleading.Hydrogeology
I wasn't asking about that. I'm asking for what interval of values you're worried about. i.e, a negative value for f will obviously underflow so you will obviously not get the same value back.Darrickdarrill
@sleeptightpupper - you should try this with negative values yourself. You'll be shocked and surprised at the results.Rydder
@SamVarshavchik f(-1) gives me 4294967295. I don't find that very surprising. Either way, it's "undefined behavior".Darrickdarrill
@sleeptightpupper I've modified my code before my first comment, please notice that.Hydrogeology
@sleeptightpupper It's not undefined behavior, it is implementation-defined behavior.Twelfthtide
@Hydrogeology use your debugger and watch the values change / or not change. That should answer your question.Murine
@dasblinkenlight "If during the evaluation of an expression, the result is not mathematically defined or not in the range of representable values for its type, the behavior is undefined."Darrickdarrill
So, what have you tried? or perhaps, what were the results of either test? Did you cout a table of the results of static_cast<>? I suppose there are 8 tests ... both directions ... MAX, MIN, 0, ... etc. What did you find out?Pallium
@sleeptightpupper - how could f(-1) possibly give you that, when it computes a comparison operation, which is a boolean operation that can return 0 or 1. With gcc 5.3.1, your f(-1), in the code you showed, returned 1. One of us is very, very confused.Rydder
@SamVarshavchik You do realize the question's been edited right?Darrickdarrill
@sleeptightpupper What does it have to do with this question? OP talks specifically about conversions, this is discussed separately.Twelfthtide
Yes, @sleeptightpupper, and f(-1) is still doing a == comparison, as shown in this question.Rydder
"If the destination type is signed, the value is unchanged if it can be represented in the destination type (and bit-field width); otherwise, the value is implementation-defined."Greatnephew
Aside from initially tagging this question C - which over complicated things, this is a very interesting post and a deserving of up votes.Radborne
T
7

The answer is "no, this is not guaranteed" for both f and g.

Here is what the standard says about it:

4.7 Integral conversions

  1. If the destination type is unsigned, the resulting value is the least unsigned integer congruent to the source integer (modulo 2n where n is the number of bits used to represent the unsigned type). [ Note: In a two’s complement representation, this conversion is conceptual and there is no change in the bit pattern (if there is no truncation). — end note ]
  2. If the destination type is signed, the value is unchanged if it can be represented in the destination type; otherwise, the value is implementation-defined.

Section 2 talks about function g. The cast of x to unsigned can cause change of representation on systems that do not use two's complement representation, so converting the number back may get you a different value.

Section 3 talks about function f. When the number is outside signed int's range, the result is implementation-defined, so one is not allowed to make any claims about the result of converting it back to unsigned.

Twelfthtide answered 26/5, 2016 at 2:25 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.