2015-07-10 88 views
3

我做這項工作2-8 K&R C練習什麼是錯的?

寫一個函數rightrot(X,N)返回整數x的值轉動到n個位位置的權利。

但是當我嘗試運行它時,我沒有得到我所期望的。

#include"stdio.h"  
int most_signficant_bit(unsigned x){ 
     int bitpos; 
     for(bitpos = -1; x!=0;++bitpos){ 
      x=x>>1; 
     } 
     return bitpos; 
    } 
unsigned rightrot(unsigned x, unsigned n){ 
     int bitpos; 
     bitpos = most_signficant_bit(x); 

     x = ((x>>n)|(((~(~0<<n))&x)<<(bitpos-n))); 
     return x; 
    } 
int main(int argc, char const *argv[]) { 
     unsigned int c1; 
     c1 = 0xff1; 

     printf("bitfield %x " 
     " after rightrot %x \n",c1, rightrot(c1, 4)); 
     return 0; 
    } 

我知道(x>>n)位域「N」次移動到以「N」少顯著位從空間複製權0000 1111 1111
(~(~0<<n))&x)複製n個少顯著位(1111 1111 0001 & 0000 0000 1111 = 0000 0000 0001),然後這些位移動到正確的位置
<<(bitpos-n)和後或在x那些位複製。
但我得到0xff而不是0x1ff或二進制0000 1111 1111而不是0001 1111 1111

那麼錯在哪裏?

+0

很有趣,當我執行代碼時,我得到'ff'而不是'8ff'或'1ff'。 – ikrabbe

+0

yeap,0x8ff是當我把<<(bitpos) – warrior

回答

5
x = ((x>>n)|(((~(~0<<n))&x)<<(bitpos-n))); 

難道你不認爲這不是它應該是

x = ((x>>n)|(((~(~0<<n))&x)<<(bitpos-n+1))); 
+1

準確地說,我差不多寫了同樣的答案..但你是一分鐘更快+1 – Srinath

+0

你是對的。謝謝!! – warrior

+0

很高興幫助:) – ameyCU

0

我認爲這表達

x = ((x>>n)|(((~(~0<<n))&x)<<(bitpos-n+1))); 

過於複雜且無法讀取。:)

而且使用此表達式的函數實現無效,因爲n可以比o中的位數多類型爲unsigned int的對象。

該函數可以被寫爲示出在示範程序按以下方式

#include <stdio.h> 
#include <limits.h> 

unsigned int rotate_right(unsigned int x, size_t n) 
{ 
    const size_t N = CHAR_BIT * sizeof(int); 

    n %= N; 

    return x >> n | x << (N - n); 
} 

int main(void) 
{ 
    unsigned int x = 0x12345678; 

    size_t n = CHAR_BIT * sizeof(int); 

    do 
    { 
     printf("%x\n", x); 
     x = rotate_right(x, CHAR_BIT/2); 
    } while (n -= CHAR_BIT/2); 
}  

程序輸出是

12345678 
81234567 
78123456 
67812345 
56781234 
45678123 
34567812 
23456781 

可以刪除頭<limits.h>和計數在一個對象的位的數目類型unsigned int使用以下功能

size_t bit_count() 
{ 
    size_t n = 0; 

    for (unsigned int i = ~0u; i; i >>= 1) ++n; 

    return n; 
} 
+0

是的,這是做這個練習的另一種方法,但是在k&r中只使用stdio.h直到本章 – warrior

+0

@warrior這不是問題。您可以用8替換CHAR_BIT並刪除頭文件:)或者,您可以使用自己的函數most_signficant_bit來計算無符號iint類型的對象中的總位數。在任何情況下,最終的功能都可以像我所展示的那樣書寫。 –

+0

好的,謝謝你的回答,你的方式最聰明我需要學習標準庫。 – warrior