什么时候在C++中改变一个值的位?

M. *_*ley 19 c++ casting

我有一个unsigned int实际存储有符号值的C++ .我想将此变量转换为a signed int,以便无符号和有符号值具有相同的二进制值.

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
Run Code Online (Sandbox Code Playgroud)

什么时候强制转换在C++中改变变量的位?例如,我知道从a int到a的转换float会改变位,因为它int是二进制补码并且float是浮点数.但其他场景呢?我不清楚C++中的规则.

在C99规范的6.3.1.3节中,它表示从无符号到有符号整数的转换是编译器定义的!

Che*_*Alf 16

类型转换可以

  • 保持概念值(可能必须更改位模式),或

  • 保持位模式(可能必须更改概念值).

保证始终保持bitpattern的唯一C++演员是const_cast.

一个reinterpret_cast是,正如它的名字所暗示的,意守位模式与简单地重新诠释它.但是该标准允许实现在如何实现方面有很大的余地reinterpret_cast.在某些情况下,reinterpret_cast可能会更改位模式.

A dynamic_cast通常会更改bitpattern和value,因为它通常会深入研究对象并返回指向所请求类型的子对象的指针/引用.

A static_cast可以改变整数和指针的位模式,但是,几乎所有现存的计算机都使用有符号整数的表示(称为二进制补码),其中static_cast不会改变位模式.关于指针,可以说,例如,当基类是非多态的并且派生类是多态的时,使用static_cast从指针派生到指针到base,反之亦然,可以改变位模式(当你比较void*指针时可以看到).现在,整数......

对于n个值位,无符号整数类型具有2 ^ n个值,范围为0到2 ^ n -1(包括).

C++标准通过添加或减去2 ^ n的合适倍数来保证该类型的任何结果都包含在该范围内.

实际上这就是C标准对它的描述; C++标准只是说操作是 2 ^ n,这意味着相同.

使用二进制补码形成有符号值 - x具有与无符号值相同的位模式 - x + 2 ^ n.也就是说,与C++标准相同的位模式保证通过将-x转换为相同大小的无符号类型.这是两个补码形式的简单基础,它正是您寻求的保证.:-)

几乎所有现存的计算机都使用两种补码形式.

因此,在实践中,您可以保证您的示例的位模式不变.