2012-04-12 50 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