I have a C++ unsigned int
which is actually storing a signed value. I want to cast this variable to a signed int
, so that the unsigned and signed values have the same binary value.
unsigned int lUnsigned = 0x80000001; int lSigned1 = (int)lUnsigned; // Does lSigned == 0x80000001? int lSigned2 = static_cast<int>(lUnsigned); // Does lSigned == 0x80000001? int lSigned3 = reinterpret_cast<int>(lUnsigned); // Compiler didn't like this
When do casts change the bits of a variable in C++? For example, I know that casting from an int
to a float
will change the bits because int
is twos-complement and float
is floating-point. But what about other scenarios? I am not clear on the rules for this in C++.
In section 6.3.1.3 of the C99 spec it says that casting from an unsigned to a signed integer is compiler-defined!
Type casting refers to changing an variable of one data type into another. The compiler will automatically change one type of data into another if it makes sense. For instance, if you assign an integer value to a floating-point variable, the compiler will convert the int to a float.
When casting from a float or numeric to an integer, the CAST function will truncate the result. For other conversions, the CAST function will round the result.
The malloc function returns a pointer value of type void* . A value of that type can be implicitly converted to any object pointer type. No cast is necessary, and in some cases using a cast can mask errors.
In the C language, casting is a construct to view a data object temporarily as another data type. When you cast pointers, especially for non-data object pointers, consider the following characteristics and constraints: You can cast a pointer to another pointer of the same IBM® i pointer type.
A type conversion can
keep the conceptual value (the bitpattern may have to be changed), or
keep the bitpattern (the conceptual value may have to be changed).
The only C++ cast that guaranteed always keeps the bitpattern is const_cast
.
A reinterpret_cast
is, as its name suggests, intended to keep the bitpattern and simply reinterpret it. But the standard allows an implementation very much leeway in how to implement reinterpret_cast
. In some case a reinterpret_cast
may change the bitpattern.
A dynamic_cast
generally changes both bitpattern and value, since it generally delves into an object and returns a pointer/reference to a sub-object of requested type.
A static_cast
may change the bitpattern both for integers and pointers, but, nearly all extant computers use a representation of signed integers (called two's complement) where static_cast
will not change the bitpattern. Regarding pointers, suffice it to say that, for example, when a base class is non-polymorphic and a derived class is polymorphic, using static_cast
to go from pointer to derived to pointer to base, or vice versa, may change the bitpattern (as you can see when comparing the void*
pointers). Now, integers...
With n value bits, an unsigned integer type has 2^n values, in the range 0 through 2^n-1 (inclusive).
The C++ standard guarantees that any result of the type is wrapped into that range by adding or subtracting a suitable multiple of 2^n.
Actually that's how the C standard describes it; the C++ standard just says that operations are modulo 2^n, which means the same.
With two's complement form a signed value -x has the same bitpattern as the unsigned value -x+2^n. That is, the same bitpattern as the C++ standard guarantees that you get by converting -x to unsigned type of the same size. That's the simple basics of two's complement form, that it is precisely the guarantee that you're seeking. :-)
And nearly all extant computers use two's complement form.
Hence, in practice you're guaranteed an unchanged bitpattern for your examples.
If you cast from a smaller signed integral type to a larger signed integral type, copies of the original most significant bit (1
in the case of a negative number) will be prepended as necessary to preserve the integer's value.
If you cast an object pointer to a pointer of one of its superclasses, the bits can change, especially if there is multiple inheritance or virtual superclasses.
You're kind of asking for the difference between static_cast
and reinterpret_cast
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With