1. 程式人生 > >不同進位制之間的轉換

不同進位制之間的轉換

 在這裡暫且只討論整型正數,二、八、十、十六進位制之間的相互轉換,以後可能會對非整型負數和其他進位制進行補充。

       首先,我研究了進位制之間相互轉換的方法,如下:

     

       從轉換關係中,我們推出發現一個結論:任何進位制數在轉換成十進位制數時,均為按權展開相加求和;十進位制數在轉換成任何進位制數時,均為除其進製取餘(這兩個結論應該不止僅限於二、四、八、十六進位制的相互轉換)。那麼,我們可以選取十進位制作為中間進位制,即在進行進位制轉換時,先把初始進位制數轉換為十進位制數,再轉換成目標進位制數。

       接下來,我們來詳細研究一下這個過程。既然以十進位制為中間進位制,那麼我們就需要分為兩種情況進行討論,初始值的進位制是十進位制 的和不是十進位制的。

       首先我們討論的是初始值不是十進位制的情況,因為它相對複雜一些。我們在得到初始值後,需要將其按權展開相加求和,在這之前,我們先來了解一下什麼是按權展開相加求和,簡單來說就是將其各個位上的數乘以其進位制的n(n是這個位上數是這個數的第n位)次方,這樣可能比較難以理解,我們來舉個例子。

        

      從這個過程中,我們可以想到,這個過程可以用一個for迴圈輸出a[i]*(b^i)做加法(其中a[i]為存放著各個位上值的陣列,b為初始值的進位制)。我們首先就需要把初始值的各個位上的值放入陣列a[i]中,這是我們需要定義的第一個方法,將其命名為Fenjie,作用是把初始值陣列化。把初始值陣列化之後,我們就要將其先轉換為十進位制數了,再進行進位制轉換,這是需要定義的第二個方法,我們將其命名為Zhuanhuan1,作用是把陣列化的初始值轉換為十進位制數。接下來就是把轉換好的十進位制數轉為目標進位制數了,再定義我們的第三個方法,將其命名為Zhuanhuan2,作用是把轉換後的十進位制數再轉換為目標進位制數。在這裡,我們需要思考一個問題,十進位制數在轉換為目標進位制數時,使用的是除其進位制而後取餘,餘數從上往下,但我們需要的是從下往上,就像這樣

             
因此,我們需要定義第四個方法Jiaohuan或者用for迴圈輸出時,用減迴圈將陣列倒著輸出來。

最後再來理一下這個進位制轉換的過程:初始值如果非十進位制,則先呼叫Fenjie方法進行陣列化,陣列化後的初始值呼叫Zhuanhuan1方法轉為十進位制,十進位制數再呼叫Zhuanhuan2方法轉換為目標進位制數。至於初始值是十進位制的,直接呼叫Zhuanhuan1方法進行轉換就ok了。

 

高效進位制轉換的三種方法

1、 使用陣列儲存資料

#include<iostream>
using namespace std;
char* Convert_16(unsigned long value)
{
    static char Buffer[sizeof(unsigned long)*2+1];//9位 空間大小,靜態空間自動賦0
    int mod;
    for(int i=sizeof(unsigned long)*2-1; i>=0; --i)//取模反向儲存
    {
        mod = value % 16;
        if(mod < 10)
        {
            Buffer[i] = mod + '0';
        }
        else
        {
            Buffer[i] = (mod-10) + 'A';
        }
        value /= 16;
    }
    return Buffer;
}
void main()
{
    unsigned long value = 4711;
    char *result = Convert_16(value);
    cout<<value<<" = "<<"0x"<<result<<endl;
}

 2.使用棧儲存資料 先入後出

#include<iostream>
#include<stack>
using namespace std;
void Convert_16(unsigned long value)
{
    stack<char> st;.//定義棧st 
    int  mod;
    while(value != 0)
    {
        mod = value % 16;
        if(mod < 10)
        {
            st.push(mod+'0');//入棧push
        }
        else
        {
            st.push((mod-10) + 'A');
        }
        value /= 16;
    }
    cout<<value<<" = "<<"0x";
    while(!st.empty())  ///不為空 則出棧 出棧 pop
    {
        cout<<st.top();
        st.pop();
    }
    cout<<endl;
}
void main()
{
    unsigned long value = 4711;
    Convert_16(value);
}

3、使用字串常量高效轉換 推薦*

#include<iostream>
#include<stack>
using namespace std;
char* Convert_16(unsigned long value)
{
    static char Buffer[sizeof(unsigned long)*2+1];
    for(int i=sizeof(unsigned long)*2-1; i>=0; --i)
    {
        Buffer[i] = "0123456789ABCDEF"[value%16];/////字串常量,模直接對應陣列的值去存入,把模的結果當做下標,餘數為3則存入3;
        value /= 16;
    }
    return Buffer;
}
void main()
{
    unsigned long value = 4711;
    char *result = Convert_16(value);
    cout<<value<<" = "<<"0x"<<result<<endl;
}


--------------------- 
資料:

1.https://blog.csdn.net/qq_37965228/article/details/79648515

2.https://blog.csdn.net/zxh1592000/article/details/78905647

2.C語言實現任意進位制數之間的轉換https://blog.csdn.net/qq_36454961/article/details/79174645