1

I would like to store a signed int32 into an unsigned uint32 such that I can extract a int32 from it later. The value of the uint32 itself isn't used when it stores an integer like this, but I can't use a union in this case unfortunately. The way I currently do this is by simply converting it:

int32  signedVar   = -500;
uint32 unsignedVar = uint32(signedVar);
func(int32(unsignedVar)); // should supply the function with -500

This appears to work, but I'm afraid it might not be portable, and that there might be needless conversions happening behind the scenes for what I'm hoping is a no-op.

Is -500 or any other negative number guaranteed to survive this conversion? If not, is there a "painless" (none of the types are changed, only the conversion method) alternative?

Edit: I'm most concerned with making sure the value in int32 is preserved in a uint32 so it can be used as a int32 of the same value later, the uint32 version is never used. (editing because SO asked me to explain how this isn't a duplicate of another question; it doesn't specify what the results of the conversion should look like, or that it needs to be symmetrical like this, making it too general to be applied here)

Anne Quinn
  • 12,609
  • 8
  • 54
  • 101
  • 1
    Why do you need to go there and back again? – NathanOliver May 18 '16 at 15:44
  • 2
    use reinterpret_cast? – Shangtong Zhang May 18 '16 at 15:48
  • @NathanOliver - tbh, laziness. There's an edge case where there can be a negative index into an array, and I don't want to write the machinery into the pipeline to deal with it – Anne Quinn May 18 '16 at 15:48
  • 1
    Possible duplicate of [Converting Signed to Unsigned and vice versa](http://stackoverflow.com/questions/26036504/converting-signed-to-unsigned-and-vice-versa) – Jonathan Mee May 18 '16 at 15:49
  • 2
    Ah. You may to to give this a read: http://stackoverflow.com/questions/13150449/efficient-unsigned-to-signed-cast-avoiding-implementation-defined-behavior – NathanOliver May 18 '16 at 15:51
  • @SlardarZhang - will `signedVar == *reinterpret_cast(&(*reinterpret_cast(&signedVar)));` always be true? (wacky code but y'know what I mean!) – Anne Quinn May 18 '16 at 15:52
  • @JonathanMee I do not think that works in all cases. If your machine does not have a twos-compliment signed integer(this is not required) I do not think it works. – NathanOliver May 18 '16 at 15:52
  • @SlardarZhang `static_cast` is what you want see standard section 4.7.2 You do not want `reinterpret_cast` see standard section 5.2.10.3. – Jonathan Mee May 18 '16 at 15:57
  • @NathanOliver Fascinating, I've been digging through the standard and it seems you're right without 2's compliment truncation can occur. – Jonathan Mee May 18 '16 at 16:00

1 Answers1

2

If your machine uses 1s-complement or sign-magnitude arithmetic (which is allowed by the C standard at least; not sure about C++), then this double conversion will convert the value -0 into 0. If your machine uses 2s complement, then this will be fine.

That said, I'm not aware of any machine built in the last 30 years that uses anything other than 2s complement for arithmetic.

Chris Dodd
  • 119,907
  • 13
  • 134
  • 226