得到字节 - 这是怎么回事?

时间:2011-09-02 13:29:58

标签: c bit-manipulation

我想从32位整数中获取指定的字节。我的错误价值,但我不知道为什么。

对此问题的限制是:

必须使用有符号位,我不能使用乘法。我特别需要知道该功能有什么问题,如下所示。

这是功能:

int retrieveByteFromWord(int word, int byte)
{
  return (word >> (byte << 3)) & 0xFF;
} 

例如:            (3)(2)(1)(0)------字节数 在字:10010011 11001100 00110011 10101000

我想返回字节2(11001100)

retrieveByteFromWord(word,2)----给出:11001100

但是对于某些情况它是错的,它不会告诉我是什么情况。

有什么想法吗?


问题在于:

您刚开始为一家公司工作,该公司正在实施一组程序来操作数据结构,其中4个有符号字节被打包成32位无符号字节。字内的字节从0(LSB)到3(MSB)编号。您已经分配了使用2的补码算术和算术右移来实现机器功能的任务,并使用以下原型:

typedef unsigned packed_t

int xbyte(packed_t word, int bytenum);

这是以前的员工尝试让他因错误而被解雇:

int xbyte(packed_t word, int bytenum)
{
  return (word >> (bytenum << 3)) & 0xFF;
}

A)代码有什么问题? B)仅使用左右移位和一次减法来编写正确的实现。

我做过B但仍然不知道A为什么是错的。是因为十进制数字像12,15,19,55一样,然后被打包成一个单词然后当我提取它们时它们不再是相同的数字???可能是这样我会快速进行一些测试......

3 个答案:

答案 0 :(得分:3)

要使用数字,请使用带符号的整数类型,例如int

要使用,请使用无符号整数类型,例如unsigned。即让word参数为unsigned类型。这就是无符号类型的用途。

要乘以8,只需编写*8(这并不意味着代码的那部分在技术上是错误的,只是因为它是人为设计且不必要的不​​可读)。

更好的是,为该幻数8创建一个自描述名称,例如*bitsPerByte(标准库称之为CHAR_BIT,它不是特别自描述也不可读。)

最后,在设计层面,考虑设计你的功能,以便使用你的功能的代码 - 每个调用 - 变得清晰可读。例如。比如int const b = byteAt( 2, x );。这可以防止例如错误。防止错误的实际参数顺序,并且由于为可读性而设计使代码更容易阅读,因此减少了花在此上的时间。 : - )

干杯&amp;第h。,

答案 1 :(得分:3)

由于这是作业,我不会给你一个完整的答案,但我会指出你正确的方向。你的问题陈述说:

  

4 签名字节打包成32位无符号。

当你按位&一个带有0xFF的32位有符号整数时,结果的最高有效位 - 即符号位 - 总是0,所以原始函数无论输入如何,都不会返回负值。


举例来说......

当你说“retrieveByteFromWord(word,2)----给出:11001100”时你错了。

您的返回类型是32位整数 - 不是8位整数。您没有返回11001100您正在返回00000000 00000000 00000000 11001100

答案 2 :(得分:2)

正数可以正常工作。您可能希望将word强制转换为无符号,以使其适用于具有MSB集的整数。

int retrieveByteFromWord(int word, int byte)
{
  return ((unsigned)word >> (byte << 3)) & 0xFF;
}