[英]Combining 2 uint16_t into into 1 uint32_t
我有2个uint16_t,我想组合成1个32位数字:
uint16_t var1 = 255; // 0000 0000 1111 1111
uint16_t var2 = 255; // 0000 0000 1111 1111
uint32_t var3 = (var1 << 16) + var2;
我希望var3为0000 0000 1111 1111 0000 0000 1111 1111 ...所以十进制16711935但我得到255(0000 0000 0000 0000 0000 0000 1111 1111)。
有任何想法吗?
谢谢
当对整数类型进行移位时,两个操作数都将首先提升,并且所得整数与提升后的左操作数具有相同的类型。
编译器将首先尝试将uint16_t
提升为int
,如果一个int
无法保存该值(即,该值大于INT_MAX),它将被提升为unsigned int
。 现在,如果您的系统使用16-bit int
,结果仍将是16位,因此只要您的shift值小于16,就将丢失左移情况下的最高有效位。未按标准定义。
在这种系统中,您需要首先转换为更宽泛的整数类型(例如uint32_t
或uint64_t
,然后左移。 为了安全起见,我们总是可以将移位的左操作数强制转换为期望的type
以使我们的代码不受编译器设计者做出的实现决定(如位宽)的影响。
在某种程度上,这取决于平台。 在我最近的系统上,我们得到了预期的结果,可以通过一个简短的程序进行演示:
#include <stdint.h>
#include <inttypes.h>
#include <stdio.h>
int main()
{
uint16_t var1 = 255; // 0000 0000 1111 1111
uint16_t var2 = 255; // 0000 0000 1111 1111
uint32_t var3 = (var1 << 16) + var2;
printf("%#"PRIx32"\n", var3);
}
输出为0xff00ff
。
但是,您的var1
和var2
在进行任何算术运算之前都会经过普通的整数提升 。 如您所见,如果提升的类型不能保存中间结果,则部分计算可能会丢失。
您可以通过在算法前显式扩展var1
来避免此问题:
uint32_t var3 = ((uint32_t)var1 << 16) + var2;
我的系统上等效的失败程序是:
#include <stdint.h>
#include <inttypes.h>
#include <stdio.h>
int main()
{
uint16_t var1 = 255; // 00ff
uint16_t var2 = 255; // 00ff
uint64_t var3 = ((uint64_t)var1 << 32) + var2;
printf("%#"PRIx64"\n", var3);
}
如果我不按所示使用演员0x1fe
来0x1fe
var1
,那么它将产生0x1fe
而不是0xff000000ff
(因为在此系统上, <<32
恰好是具有32位无符号类型的无操作)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.