说我有以下代码:
uint32_t fillThisNum(int16_t a, int16_t b, int16_t c){
uint32_t x = 0;
uint16_t temp_a = 0, temp_b = 0, temp_c = 0;
temp_a = a << 24;
temp_b = b << 4;
temp_c = c << 4;
x = temp_a|temp_b|temp_c;
return x;
}
基本上我要做的就是用32位数字填充我以后可以提取的位信息来执行不同的操作。
参数a
将保存“数据”的前24位,b
将保存“数据”的下4位,c
将保存“数据”的最后4位”
我有几个问题:
uint32_t a = int32_t b;
)非常感谢任何建议/提示/提示,谢谢。
答案 0 :(得分:1)
- 参数必须与函数类型的位长度相同,是否必须是无符号的?
醇>
不,参数和返回值可以是不同的类型。
- 我可以将unsigned int分配给signed int吗? (即uint32_t a = int32_t b;)
醇>
是的,该值将从有符号值转换为无符号值。 &#34; b&#34;中的位将保持不变,所以虽然&#34; b&#34;是2的补充,&#34; a&#34;将是一个正32位数。
所以,例如,让int8_t c = -127。如果你执行一项任务uint8_t d = c,那么&#34; d&#34;将是129。
- 我可以使用16位参数填充32位数字,只要它们不超过32位返回值的长度。
醇>
如果那样,那就意味着你在代码中的表现方式:
x = temp_a|temp_b|temp_c;
是的,这很好,但有一点需要注意:@chux提到:你不能将n位值移位n位以上。如果你想在x中设置比第15位更重要的位,那么这样做的方法是设置一个具有32位值而不是16位值的临时掩码。
答案 1 :(得分:1)
编写此代码的正确方法是:
uint32_t fillThisNum(uint32_t a, uint32_t b, uint32_t c)
{
// mask out the bits we are not interested in
a &= 0xFFFFFF; // save lowest 24 bits
b &= 0xF; // save lowest 4 bits
c &= 0xF; // save lowest 4 bits
// arrange a,b,c within a 32-bit unit so that they do not overlap
return (a << 8) + (b << 4) + c;
}
通过对参数使用无符号类型,可以避免签名算术溢出,符号扩展等问题。
在调用函数时将签名值作为参数传递是可以的,这些值将转换为无符号值。
通过使用uint32_t
作为参数类型,您可以避免在进行转换时声明任何临时变量或担心类型宽度。通过这种方式,您可以更轻松地编写清晰的代码。
你没有有这样做,但这是确保你不犯任何错误的简单方法。