1

我想将有符号值转换为无符号值(例如int8_tto uint8_t),但它也必须保留其位。

我该怎么做?

4

3 回答 3

2

在实践中:您可以简单地将带符号的值分配给uint8_t,

u = i;

或者您可以使用带符号的值对其进行初始化,

uint8_t u = i;

这假定了一个二进制补码有符号整数表示,这在今天普遍使用。使用该表示,位被准确地保留。“在实践中”的限定是指该假设。


例如,在现代机器上,例如 -42 的 8 位有符号表示是位模式编号 -42 + 256,即(位模式编号)214。标准保证将其转换为无符号以产生相同的模 256 .所以它是相同的bitpattern,即bitpattern 214。


标准很好地定义了从有符号到无符号的转换,尽管位模式(1)的保留通常只是一种实践效果(所有现代计算机都是这样设计的)。但是,如果无法表示无符号值,则相反,您会遇到编译器特定的效果。这种转换需要更加小心,因为这是编译器自行决定的问题,而不是硬件级别的实际保证。


(1) 正如 MM 在他的回答中解释的那样,您的示例中的特定有符号类型int8_t, 是因为 C11 在 C 中得到保证的二进制补码。我在 C99 标准的最终草案中没有看到这种语言,所以大概是在 C99 中不存在,因此在基于 C99 的 C++11 或 C++14 中也不存在,但在我认为基于 C11 的 C++17 中可能存在。

于 2015-12-26T03:38:40.907 回答
0

使用这些intN_t类型,您可以简单地编写:

int8_t i = something;
uint8_t u = i;

因为这些类型需要使用 2 的补码表示,其中定义此转换以保留位。

参考:C++14 [cstdint.syn]/2:

头文件定义了与 C 标准中的 7.18 相同的所有函数、类型和宏

和 C11 7.20.1.1/1 (C99 7.18.1.1):

typedef 名称intN_t指定一个有符号整数类型,其宽度N、无填充位和二进制补码表示。


要保留其他整数类型的表示,请使用:

int i = something;
unsigned int i = *(unsigned int *)&i;

您可以使用任何一对对应的有符号和无符号类型来执行此操作。除了可能生成陷阱表示之外,它是安全的。

于 2015-12-26T04:22:17.940 回答
0

尝试显式类型转换。使用 static_cast 的(不安全的)类型转换对于获取变量的“原始字节”是必要的。要将 an 的值转换为给定类型,请编写以下内容:

static_cast<type_to_convert_to>(expression)

使用 static_cast 强制转换在编译时进行静态检查。

#include <iostream>


int main() {

    int8_t i {11};
    uint8_t i2 = static_cast<uint8_t>(i);
    std::cout << "i occupies " <<  sizeof(i) << " bytes." << std::endl;
    std::cout << "i2 occupies " << sizeof(i2) << " bytes." << std::endl;


}
于 2015-12-26T05:10:24.787 回答