2012-04-12 149 views
1

这里的问题是什么,我现在有,我只是不明白它是如何错误的检索32位整数字节...使用位运算符

getByte - Extract byte n from word x Bytes numbered from 0 (LSB) to 3 (MSB) Examples: getByte(0x12345678,1) = 0x56 Legal ops: ! ~ & ^| + << >> Max ops: 6 Rating: 2

int getByte(int x, int n) { 
    return ((x << (24 - 8 * n)) >> (8 * n)); 
} 
+1

什么没有关于它的工作(很明显的)想法? – 2012-04-12 22:21:51

+0

这是我得到的错误:错误:测试getByte(-2147483648 [0x80000000],3 [0x3])失败... ...给出-128 [0xffffff80]。应该是128 [0x80] – asdfghjkl 2012-04-12 22:24:48

+0

在使用非法操作员方面是错误的。 '-'运算符没有在“Legal ops”下列出 – idefixs 2012-04-12 22:30:40

回答

11

您的移动没有​​任何意义 - 首先,你转移由(24 - 8N)左位,那么您可以通过8N位移回右。为什么?另外,这是错误的。如果n为0,则将x向左移位24位并返回该值。试用笔和纸,看看这是完全错误的。

正确的做法是做:

int getByte(int x, int n) { 
    return (x >> 8*n) & 0xFF; 
} 
+0

这样做更有意义谢谢,一旦我用笔和纸看到哪里我犯了这个错误很完美 – asdfghjkl 2012-04-12 22:34:21

+0

不客气! – Rob 2012-04-12 22:35:23

+0

此外,您只能切换到寄存器大小(32位,64位或64位)。否则,它的未定义的行为。所以'getByte(0xffffffff,16)'会导致未定义的行为。 – jww 2014-07-12 11:34:12

1

我不明白你的功能如何工作。试试这个:

int getByte(int x, int n) 
{ 
    return (x >> (8 * n)) & 0xFF; 
} 
6

除非我完全错了,你的代码是不正确数学。

getByte(0x000000ff, 0) { 
    24 - 8 * n = 24; 
    8 * n = 0; 
    0x000000ff << 24 = 0xff000000; 
    0xff000000 >> 0 = 0xff000000; 
    return 0xff000000; // should return 0xff 
} 

没有被允许使用运营商-尤其*是一个问题(不能做* 8)。我想出了这个:

uint8_t getByte (uint32_t x, int n) { 
    switch (n) { 
     case 0: 
      return x & 0xff; 
     case 1: 
      return (x >> 8) & 0xff; 
     case 2: 
      return (x >> 16) & 0xff; 
     case 3: 
      return x >> 24; 
    } 
} 

不完全漂亮,但它符合问题描述:6个操作符,所有这些都是合法的。

编辑:只是有关于如何避免* 8

uint8_t getByte (uint32_t x, int n) { 
    return (x >> (n << 3)) & 0xff; 
} 
+0

是 - 执行左移相当于乘以2.所以左移3次是2^3 = 8。 – user1527227 2014-07-21 01:44:16

+0

@idefixs谢谢!你的解决方案很完美! – SeniorShizzle 2015-03-04 01:16:03

+0

这应该是被接受的答案,因为它避免了“非法”操作。 – Alain 2017-01-14 20:22:23