开发者

Get byte - how is this wrong?

I want to get the designated byte from a 32 bit integer. I am getting wrong values but I don't know why.

The restrictions to this problem are:

  • Must use signed bits, and I can't use multiplication.
  • I specifically need to know what is wrong with the function as it's below.

Here is the function:

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

ex: (3) (2) (1) (0) ------ byte number In word: 10010011 11001100 00110011 10101000

I want to return byte 2 (1100 1100).

retrieveByteFromWord(word, 2) ---- gives: 1100 1100

But for some cases it's wrong and it won't tell me what case.

Any ideas?


Here is the problem:

You just started working for a company that is implementing a set of procedures to operate on a data structure where 4 signed bytes are packed into a 32 bit unsigned. Bytes within the word are numbered from 0(LSB) to 3(MSB). You have been assigned the task of implementing a function for a machine using 2's complement arithmetic and arithmetic r开发者_高级运维ight shifts with the following prototype:

typedef unsigned packed_t

int xbyte(packed_t word, int bytenum);

This is the previous employees attempt which got him fired for being wrong:

int xbyte(packed_t word, int bytenum)
{
  return (word >> (bytenum << 3)) & 0xFF;
}
  • A) What is wrong with the code?

  • B) Write a correct implementation using only left and right shifts and one subtraction.

I have done B but still don't know why A is wrong. Is it because the decimal numbers going in like 12, 15, 19, 55 and then getting packed into a word and then when I extract them they aren't the same number anymore??? It might be so I am going to run some tests real fast...


As this is homework I won't give you a full answer, but I'll point you in the right direction. Your problem statement says that:

4 signed bytes are packed into a 32 bit unsigned.

When you bitwise & a 32 bit signed integer with 0xFF the most significant bit - i.e. the sign bit - of the result is always 0, so the original function never returns a negative value regardless of the input.


By way of example...

When you say "retrieveByteFromWord(word, 2) ---- gives: 11001100" you're wrong.

Your return type is a 32 bit integer - not an 8 bit integer. You're not returning 11001100 you're returning 00000000 00000000 00000000 11001100.


To work with numbers, use signed integer types such as int.

To work with bits, use unsigned integer types such as unsigned. I.e. let the word argument be of type unsigned. That is what the unsigned types are for.

To multiply by 8, write just *8 (this does not mean that that part of the code is technically wrong, just that it is artificially contrived and needlessly unreadable).

Even better, create a self-describing name for that magic number 8, e.g. *bitsPerByte (the standard library calls it CHAR_BIT, which is not particularly self-describing nor readable).

Finally, at the design level, think about designing your functions so that the code that uses a function of yours – each call – becomes clear and readable. E.g. like int const b = byteAt( 2, x );. That can prevent bugs by e.g. preventing wrong actual argument order, and since designing for readability makes the code easier to read, it reduces time spent on that. :-)

Cheers & hth.,


Works fine for positive numbers. You may want to cast word to unsigned to make it work for integers with the MSB set.

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

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜