gpt4 book ai didi

c++ - C++ 中的转换何时改变值的位?

转载 作者:IT老高 更新时间:2023-10-28 21:57:32 27 4
gpt4 key购买 nike

我有一个 C++ unsigned int,它实际上存储了一个带符号的值。我想将此变量转换为 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

强制转换何时更改 C++ 中变量的位?例如,我知道从 int 转换为 float 会改变位,因为 int 是二元补码并且 float 是 float 。但是其他情况呢?我不清楚 C++ 中的规则。

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

最佳答案

类型转换可以

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

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

唯一保证始终保持位模式的 C++ 转换是 const_cast

reinterpret_cast 顾名思义,旨在保留位模式并简单地重新解释它。但是该标准允许实现在如何实现 reinterpret_cast 方面有很大的余地。在某些情况下,reinterpret_cast 可能会改变位模式。

dynamic_cast 通常会同时更改位模式和值,因为它通常会深入研究对象并返回指向所请求类型的子对象的指针/引用。

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

使用 n 个值位,无符号整数类型有 2^n 个值,范围为 0 到 2^n-1 (包括在内)。

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

实际上 C 标准就是这样描述它的; C++ 标准只是说运算是 modulo 2^n,意思是一样的。

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

几乎所有现存的计算机都使用二进制补码形式。

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

关于c++ - C++ 中的转换何时改变值的位?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4218465/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com