我想将有符号值转换为无符号值(例如,int8_t
到uint8_t
),但它也必须保留其位。
我该怎么做?
答案 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;
}