在C中移位位值

时间:2014-10-09 19:15:19

标签: c bit unsigned bit-shift

说我有以下代码:

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位”

我有几个问题:

  1. 参数必须与函数类型的位长度相同,是否必须是无符号的?
  2. 我可以将unsigned int分配给signed int吗? (即uint32_t a = int32_t b;
  3. 我可以使用16位参数填充32位数字,只要它们不超过32位返回值的长度。
  4. 非常感谢任何建议/提示/提示,谢谢。

2 个答案:

答案 0 :(得分:1)

  
      
  1. 参数必须与函数类型的位长度相同,是否必须是无符号的?
  2.   

不,参数和返回值可以是不同的类型。

  
      
  1. 我可以将unsigned int分配给signed int吗? (即uint32_t a = int32_t b;)
  2.   

是的,该值将从有符号值转换为无符号值。 &#34; b&#34;中的位将保持不变,所以虽然&#34; b&#34;是2的补充,&#34; a&#34;将是一个正32位数。

所以,例如,让int8_t c = -127。如果你执行一项任务uint8_t d = c,那么&#34; d&#34;将是129。

  
      
  1. 我可以使用16位参数填充32位数字,只要它们不超过32位返回值的长度。
  2.   

如果那样,那就意味着你在代码中的表现方式:

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作为参数类型,您可以避免在进行转换时声明任何临时变量或担心类型宽度。通过这种方式,您可以更轻松地编写清晰的代码。

你没有这样做,但这是确保你不犯任何错误的简单方法。