什么时候转换在C ++中改变一个值的位? [英] When does casting change a value's bits in C++?
问题描述
我有一个C ++ unsigned int
,它实际上是存储一个有符号的值。我想将此变量转换为 signed int
,以便无符号和有符号值具有相同的二进制值。
unsigned int lUnsigned = 0x80000001;
int lSigned1 =(int)lUnsigned; // ligned == 0x80000001?
int lSigned2 = static_cast< int>(lUnsigned); // ligned == 0x80000001?
int lSigned3 = reinterpret_cast< int>(lUnsigned); //编译器不喜欢这个
当转换改变C ++中的一个变量的位例如,我知道从 int
转换为 float
会更改位,因为 int
是二进制补码, float
是浮点型。但是其他情况呢?我不清楚C ++中的规则。
在C99规范的6.3.1.3节中,说从无符号到有符号整数的转换是编译器 -
类型转换
-
保留概念值(必须更改bitpattern )
<
唯一的C ++强制转换总是保持bitpattern为 const_cast
。
A reinterpret_cast
是,正如其名字所暗示的,旨在保持bitpattern,只是重新解释它。但是标准允许实现非常多的空间如何实现 reinterpret_cast
。在某些情况下, reinterpret_cast
可能会更改bitpattern。
A dynamic_cast
通常改变bitpattern和value,因为它通常深入一个对象,并返回一个指向/请求类型的子对象的引用。
A static_cast
可以改变整数和指针的位模式, ,几乎所有现存的计算机都使用有符号整数(称为二的补码) $ c> static_cast 不会更改bitpattern。关于指针,足以说,例如,当一个基类是非多态的,并且一个派生类是多态的,使用 static_cast
从指针到派生指针到base,反之亦然,可以改变bitpattern(正如你在比较 void *
指针时可以看到的)。现在,整数...
使用 n 值位,无符号整数类型具有2 ^在范围0到2 ^ n
-1(包括)。C ++标准保证类型的任何结果<通过添加或减去2 ^ n的合适倍数
,将包装到该范围。实际上,这是C标准描述的方式; C ++标准只是说操作是模 2 ^ n ,这意味着相同。>二进制补码形式有符号值 - x 具有与无符号值 x + 2 ^ n相同的位模式。也就是说,与C ++标准相同的位模式保证通过将 x 转换为相同大小的无符号类型。这是二进制补码形式的简单基础,这正是您寻求的保证。 : - )
几乎所有现存的电脑都使用二进制补码形式。
保证您的示例不变的bitpattern。
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!
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.
这篇关于什么时候转换在C ++中改变一个值的位?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!