如何根据其位将有符号整数值转换为无符号?

时间:2015-12-26 02:49:28

标签: c++ integer int uint8t

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

我该怎么做?

3 个答案:

答案 0 :(得分:2)

实际上:您只需将签名值分配给uint8_t

即可
u = i;

或者您可以使用签名值

对其进行初始化
uint8_t u = i;

这假定二的补码有符号整数表示,这在今天是普遍使用的。通过该表示,位被精确保留。 “实践中”资格是指这种假设。

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

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

(1)作为M.M.在his answer中解释了示例中的特定签名类型int8_t,是因为C11已经保证了C中的两个补码。我在C99标准的最终草案中没有看到该语言,所以据推测它在C99中不存在,因此不在基于C99的C ++ 11或C ++ 14中,但可​​能存在于C ++ 17中,我认为它基于C11。 功能

答案 1 :(得分: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;

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

答案 2 :(得分:0)

尝试使用显式类型转换。使用static_cast进行(不安全)类型转换是获取"原始字节"一个变量。 要将a的值转换为给定类型,请编写以下内容:

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;


}