國外做化學申報的網(wǎng)站做推廣的公司
十進制轉任意進制
簡單回憶一下十進制我們是怎么轉換成二進制的(短除法):
我們會將十進制數(shù)不斷的進行除2操作,并且記錄下每一次的余數(shù)(這個余數(shù)就是我們最終求的二進制數(shù)的組成部分)。
以下以12D舉例,將其轉換成二進制數(shù):
? ? ? ? ? ? ? ? ? ? ? ? ? ? 除2? ? ?被除數(shù)? ? ? ? ? ? ? ?-------------? ?余數(shù)
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 2? /? ? ?1 2? ? ? ? ? ? ? ? ? ?---------------? ? 0? ? (=12%2)
? ? 商&下一個被除數(shù)? ? ? ? ? 6 (=12/2)? ? ? ? --------------? ? ?0? ?(=6%2)
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 3? (=6/2)? ? ? ? ?--------------? ? ?1? ? ?(=3%2)
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?1 (=3/2)? ? ? ? ? --------------? ? ?1? ? ?(=1%2)
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?0 (=1/2,結束)
計算出的余數(shù)由下往上組合就是我們要求的二進制數(shù),即
那么我們就要把這個思路轉換成相對應的計算機代碼了。
我們僅僅需要一個循環(huán)就可以完成這件事:
?
//n是我們待轉化的十進制數(shù)
int ans[100];//用于存放我們的計算結果
int len=0;//用于記錄我們轉換的二進制有多少位
while(n!=0){ans[len++]=n%2;//取余運算,將結果保存同時位數(shù)len加一n/=2;//記錄下一個被除數(shù)
}
//輸出我們的二進制時,別忘了要逆序輸出(短除法)
for(int i=len-1;i>=0;i--){printf("%d",ans[i]);
}
現(xiàn)在我們把這個思路拓展到x進制的轉換。
首先,在所有x小于10的x進制轉換中,都可以沿用上面的這個思路,只需要更改%2和/2即可:
//n是我們待轉化的十進制數(shù),x代表我們要轉化的是幾進制
int ans[100];//用于存放我們的計算結果
int len=0;//用于記錄我們轉換的x進制有多少位
while(n!=0){ans[len++]=n%x;//取余運算,將結果保存同時位數(shù)len加一n/=x;//記錄下一個被除數(shù)
}
//輸出我們的x進制時,別忘了要逆序輸出(短除法)
for(int i=len-1;i>=0;i--){printf("%d",ans[i]);
}
但對于x>10的進制轉換,這樣做顯然不太可行,拿十六進制舉例,大于9的數(shù)使用字母進行表示。
為了能夠將十進制以上和以下進行統(tǒng)一,我們修改以下我們的代碼。
注意:以下代碼可以適用于所有十進制轉任意進制的情況:
#include <stdio.h>
#include <stdlib.h>
#define MAX 30
int main(){int n;char ans[MAX];//更改結果類型,采用char保存結果int len;int x;//代表轉成幾進制scanf("%d",&x);while(scanf("%d",&n)!=EOF){len=0;while(n!=0){if(n%x<10)ans[len++]=n%x+'0';//小于10直接存數(shù)else ans[len++]=n%x-10+'A';//大于10存放字母n/=x;}for(int i=len-1;i>=0;i--){//結果逆序輸出printf("%c",ans[i]);}printf("\n");}return 0;
}
任意進制轉十進制
同樣先來看二進制,我們采用的是乘法。
平時我們想把二進制轉十進制很簡單,直接按位計算相加就行:
?那么轉換成代碼我們又該怎么表示呢?
我們從最高位開始計算():
?
?以下代碼即為二進制的轉換:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX 30
int main(){char s[30];//代表二進制數(shù)int ans=0;//存儲十進制答案scanf("%s",s);int len=strlen(s);for(int i=0;i<len;i++){ans*=2;ans+=s[i]-'0';}printf("%d\n",ans);return 0;
}
拓展到任意進制與上述方法類似,就不再贅述了,直接上代碼:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX 30
int main(){char s[30];//代表二進制數(shù)int ans=0;//存儲十進制答案int x;//用于記錄轉換為x進制scanf("%d",&x);int len;while(scanf("%s",s)!=EOF){len=strlen(s);ans=0;for(int i=0;i<len;i++){ans*=x;if(s[i]>='0'&&s[i]<='9')ans+=s[i]-'0';else ans+=s[i]-'A'+10;}printf("%d\n",ans);}return 0;
}
大數(shù)進制轉換
思路來源:大數(shù)的進制轉換_大數(shù)進制轉換-CSDN博客
?指路這位大佬。
?題目描述:將一個長度最多為30位數(shù)字的十進制非負整數(shù)轉換為二進制數(shù)輸出
之前我們在進行十進制轉二進制時,不斷地在重復模2、除2的操作。但這對于大數(shù)來說并不好實現(xiàn)(因為之前我們使用一個整型存儲數(shù)據(jù),而現(xiàn)在我們使用字符串來存儲大數(shù))
大數(shù)除法
根據(jù)以上那位大佬的思路,我明白了每一次除法運算的內在流程。
除法運算從被除數(shù)(344)的最高位開始,每一輪除法都取被除數(shù)的一位出來進行運算。
應該進行幾輪除法由被除數(shù)(344)的位數(shù)決定,比如這里344一共有個十百三位,也就需要進行3輪除法。
在每一輪除法中,我們都會得到一個商和余數(shù)(回歸到余數(shù)最本質的定義:剩余的、沒有除完的數(shù)稱為余數(shù),因此在下一輪除法操作時要將上一輪的余數(shù)帶上)。
所以現(xiàn)在基本上已經(jīng)理清楚了,我們所要求的除法結果其實就是每一輪的商合在一起的結果。
#include <stdio.h>
#include <string.h>
#include <stdlib.h>int main() {char x[1000];//我們的十進制待轉換數(shù)char* tmp;//用于存儲被除數(shù)int len = strlen(x);//用于保存被除數(shù)的長度//以下定義看名字應該也知道是什么,寫的是拼音int yushu, shang, beichushu;int count;//count用于記錄下一輪被除數(shù)應得的長度char ans[1000];//用于記錄二進制結果int ans_len;//代表二進制結果的位數(shù)while(scanf("%s", x)!=EOF){tmp=x;len=strlen(x);ans_len=0;//以下循環(huán)是計算一個完整的二進制數(shù)的過程while (len != 0)//當被除數(shù)不等于0的時候,就需要進行循環(huán){count = 0;yushu = 0;shang = 0;//這個循環(huán)才是一輪除法的循環(huán)過程for (int i = 0; i < len; i++) {beichushu = yushu * 10 + tmp[i] - '0';yushu = beichushu % 2;shang = beichushu / 2;x[count++] = shang + '0';//記錄下每一次運算的商}ans[ans_len++] = yushu + '0';//以下操作是將商前面多余的零刪除掉,只留下有效位的操作int j = 0;while (x[j] == '0')j++;len=0;while (j < count) {tmp[len++] = x[j++];}}for (int i = ans_len - 1; i >= 0; i--) {printf("%c", ans[i]);}printf("\n");}return 0;}
?