繁体   English   中英

使用ansi C中的位运算符将unsigned char分配给unsigned short

[英]Assign unsigned char to unsigned short with bit operators in ansi C

我知道可以将无符号的char分配给无符号的short,但是我想更好地控制如何将位实际分配给无符号的short。

unsigned char UC_8;
unsigned short US_16;

UC_8 = 0xff;
US_16 = (unsigned char) UC_8;

现在,来自UC_8的位放置在US_16的低位中。 由于我当前正在处理的应用程序与安全相关,因此我需要对转换进行更多控制。 可以使用位运算符控制转换吗? 因此,我可以指定将无符号字符的8位放在较大的16位无符号short变量中的位置。

我的猜测是,将掩膜与其他位运算符结合使用是可能的,可能是左/右移位。

UC_8 = 0xff;
US_16 = (US_16 & 0x00ff) ?? UC_8; // Maybe masking?

我尝试了不同的组合,但没有提出一个明智的解决方案。 我正在使用ansi C,并且如前所述,需要更多控制如何在较大的变量中实际设置位。

编辑:我的问题或担忧来自CRC生成函数。 由于有时会计算出16位CRC,因此它将并且应该始终返回一个无符号的short。 但是有时它应该改为计算8位CRC,然后将8位放在16位返回变量中的8个LSB上。 然后在8个MSB上只应包含零。

我想说些类似的话:

US_16(7 downto 0) = UC_8; 
US_16(15 downto 8) = 0x00;

如果只是进行转换,是否可以保证将位始终放在较大变量的低位上? (在所有不同的体系结构上)

你是什​​么意思,“控制”?

C标准明确地定义了无符号二进制格式的位位置和重要性。 根据数字定义,16位变量的某些位为“低”,它们将保留8位变量的模式,其他位设置为零。 没有歧义,没有回旋余地,没有其他可控制的东西。

也许旋转位会帮助您:

US_16 = (US_16 & 0x00ff) | ( UC_8 << 8 );

位结果将是:
C-UC_8位
S-US_16位
CCCC CCCC SSSS SSSS,分别:SSSS SSSS是US_16的后8位

但是,如果UC_8为1,而US_16为0,则US_16将为512。这是您的意思吗?

US_16 = (US_16 & 0xff00) | ( UC_8 & 0x00ff );

如果重要的是使用ansi C,并且不限于特定的实现,则您不应该假定sizeof(short)==2。为什么还要麻烦将无符号字符转换为无符号字符(同一件事)? 尽管现在可以安全地假设char为8位,即使不能保证。

uint8_t UC_8;
uint16_t US_16;
int nbits = ...# of bits to shift...;
US_16 = UC_8 << nbits;

显然,如果移位超过15位,则可能不是您想要的。 如果您需要重新排列位,而不仅仅是将它们移到某个位置,则必须单独设置它们

int sourcebit = ...0 to 7...;
int destinationbit = ...0 to 15...;
// set
US_16 |= (US_8 & (1<<sourcebit)) << (destinationbit - sourcebit);
// clear
US_16 &= ~((US_8 & (1<<sourcebit)) << (destinationbit - sourcebit));

注意:只是写过,没有测试。 可能不是最佳的。 等等等等等等。 但类似的东西会起作用。

US_16=~-1|UC_8;

这是你想要的吗?

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM