将int转换为byte数组时,是否需要使用掩码?

3

假设你有一个整数并且想将其转换为字节数组。在搜索了各种资料后,我发现有两种方法可以实现,一种是仅使用移位,另一种是先移位再进行掩码处理。我理解移位部分,但是为什么需要进行掩码处理呢?

例如,情景1:

uint8 someByteArray[4];
uint32 someInt;

someByteArray[0] = someInt >> 24;
someByteArray[1] = someInt >> 16;
someByteArray[2] = someInt >> 8;
someByteArray[3] = someInt;

场景2:
uint8 someByteArray[4];
uint32 someInt;

someByteArray[0] = (someInt >> 24) & 0xFF;
someByteArray[1] = (someInt >> 16) & 0xFF;
someByteArray[2] = (someInt >> 8) & 0xFF;
someByteArray[3] = someInt & 0xFF;

有选择一个而不是另一个的原因吗?

1
在这段特定的代码中,掩码是多余的。其他变体的代码可能需要它。此外,如果不使用掩码,一些编译器会给出虚假警告。 - undefined
@YuHao 已修复,谢谢! - undefined
如果您不需要这个掩码,去除它可以节省四个“and”机器指令。 - undefined
@Lorehead 似乎不太可能 - undefined
如果CHAR_BIT == 9,这在理论上是可能的,并且在历史上确实发生过,那么掩码确保事情正常运行。一些DSP芯片的CHAR_BIT == 16。对于CHAR_BIT == 8的系统(大多数当前系统),这是不必要的。 - undefined
显示剩余2条评论
1个回答

2

uint8uint32不是C语言中的标准类型。我认为它们分别代表8位和32位无符号整数类型(例如由微软编译器支持的供应商特定扩展)。

无论如何...

掩码更通用-它确保结果在someByteArray元素或someInt的实际类型不同的情况下介于00xFF之间。

在这种特殊情况下,这没有任何区别,因为将uint32转换为uint8保证使用模算术(模0xFF + 0x01等于0x100或十进制的256)。但是,如果您的代码更改为使用不同类型的变量或数组,则需要进行掩码以确保结果介于0255之间(包括两个端点)。

有些编译器使用掩码可以避免编译器警告(它有效地告诉编译器表达式产生的值在00xFF之间,可以存储在8位unsigned中)。但是,其他一些编译器会抱怨将较大类型转换为8位类型的行为。因此,有时会看到第三种变体,它真正展示了“安全第一”的心态。

uint8 someByteArray[4];
uint32 someInt;

someByteArray[0] = (uint8)((someInt >> 24) & 0xFF);
someByteArray[1] = (uint8)(someInt >> 16) & 0xFF);
someByteArray[2] = (uint8)((someInt >> 8) & 0xFF);
someByteArray[3] = (uint8)(someInt & 0xFF);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接