1. 程式人生 > >【C語言】求一個數的二進位制位模式從左到右翻轉後對應的十進位制值。

【C語言】求一個數的二進位制位模式從左到右翻轉後對應的十進位制值。

用函式unsigned int reverse_bit(unsigned int value)實現想要的功能

value是我們想要求的值。

#include <stdio.h>
#include <math.h>
unsigned int reverse_bit(unsigned int value)
{
    int sum= 0;
    int n = 31;
    for(;value != 0,n != 0; value = value >> 1,n--) 
    { 
            if(value & 1)
            {
                sum += 1
*pow(2,n); } } return sum; } int main () { printf("%u\n",reverse_bit(25)); return 0; }

本題用到數學庫的函式pow,其作用是計算冪,比如pow(2,n)是計算2的n次冪。
大致思路是:一個數–>00000000 00000000 00000000 00011001
當最後一位是1時,我們都將它乘以2的31次方,接著將31減1(冪數減減),並累計每次乘積和;若最後一位是0則只進行冪數減減。

但是如果最後一位是1,那麼每次都需要進行累加和計算,所以,這樣的程式,效率往往還是很差的。上面的程式感覺沒有錯誤,但是當你輸入1時,看看執行結果是不是你想要得到的。所以上面的程式是錯誤的。

針對上面程式,下面提供了另一種解決方案:

#include <stdio.h>
#include <math.h>
unsigned int reverse_bit(unsigned int value)
{
    int ret = 0;
    int one = 0;
    int i = 0;
    for(i=0; i<32; i++)
    {
        one = value & 1;
        ret = ret | one;
        ret <<= 1;
        value = value >> 1
; } return ret; } int main () { printf("%u\n",reverse_bit(25)); return 0; }

這個程式主要採用了移位運算子,我們來驗證一下結果:

當我們看到執行結果中的25對應二進位制翻轉後的十進位制數並不符合我們的要求時,肯定知道程式寫錯了,但是你知道錯在哪裡嗎?我們不妨把實參改為1,即把主函式改為:

int main ()
{
    printf("%u\n",reverse_bit(1)); 
    return 0;
}

讓我們看看結果:

此時你發現如果把1移到最高位,輸出的應該是2147483648,但是為什麼卻是0呢?

那我們再把主函式改成:

int main ()
{
    printf("%u\n",reverse_bit(2147483648)); 
    return 0;
}

我們再來看看結果:

此時執行結果為什麼不是1而是2呢?我們發現在32位系統下,本來我們只需要移動31次就能達到把最低位移到最高位上,而程式的for迴圈中也正是移動31次。當進入執行for迴圈時,ret是在執行完一次操作後才開始左移,所以無形當中已經增加了一次左移操作。那好,既然執行結果不正確,是因為ret多移動了一位,那麼我們就試著把for迴圈中的32改成31,也就是:

for(i=0; i<31; i++)
    {
        one = value & 1;
        ret = ret | one;
        ret <<= 1;
        value = value >> 1;
    }

主函式中的輸出我們依然用:

printf("%u\n",reverse_bit(1));

緊接著我們驗證一下結果:

結果對了!那麼程式就對了!
那麼我們試著把主函式改為:

int main ()
{
    printf("%u\n",reverse_bit(2147483648)); 
    return 0;
}

我們再來驗證一下結果

為什麼結果依然不是1呢?我們換個角度思考,既然ret是在第一次操作後多移動了一次,那麼我們可不可以在ret執行第一次操作之前先移動一位,而ret初始化為0,所以既然一共要移動31位,又不影響執行結果,那麼我們可以改變一下for迴圈中語句的執行順序

我們看看正確的程式:

#include <stdio.h>
#include <math.h>
unsigned int reverse_bit(unsigned int value)
{
    int ret = 0;
    int one = 0;
    int i = 0;
    for(i=0; i<32; i++)
    {
        ret <<= 1;
        one = value & 1;
        ret = ret | one;
        value = value >> 1;
    }
    return ret;
}
int main ()
{
    printf("%u\n",reverse_bit(1)); 
    return 0;
}

此時再去驗證執行結果是否正確的工作就留給你們啦~~~~