按照 “先余为低位,后余为高位“这条铁律,其结果为1100.
这是书上教我们的常规思路(可惜按这个的话,大数是没法考虑的,因为假如这里不是12,而是一个1000位的大数,由于是是对大数的整体进行取余运算,不使用大数类及其除法操作,又如何得以进行呢?),可我们的目的是不使用大数类,那么现在我们就来换一个视角来看这个问题,12是一个十位数,十位上是1,个位上是2,按照我们正常的思维来看,这个计算应该是下面这样的:
这一轮完毕后,需要把得到的商变成下一轮的被除数,继续上述的运算,直到被除数为0才停止。
#include <stdio.h> #include <string.h> char str[1000];//输入字符串 int start[1000],ans[1000],res[1000]; //被除数,商,余数 //转换前后的进制 const int oldBase = 10; const int newBase = 2; void change() {//各个数位还原为数字形式 int i,len = strlen(str); start[0] = len; for(i=1;i<= len;i++) { if(str[i-1] >= '0' && str[i-1] <= '9') { start[i] = str[i-1] - '0'; } } } void solve() { memset(res,0,sizeof(res));//余数初始化为空 int y,i,j; //模n取余法,(总体规律是先余为低位,后余为高位) while(start[0] >= 1) {//只要被除数仍然大于等于1,那就继续“模2取余” y=0; i=1; ans[0]=start[0]; // while(i <= start[0]) { y = y * oldBase + start[i]; ans[i++] = y/newBase; y %= newBase; } res[++res[0]] = y;//这一轮运算得到的余数 i = 1; //找到下一轮商的起始处 while((i<=ans[0]) && (ans[i]==0)) i++; //清除这一轮使用的被除数 memset(start,0,sizeof(start)); //本轮得到的商变为下一轮的被除数 for(j = i;j <= ans[0];j++) start[++start[0]] = ans[j]; memset(ans,0,sizeof(ans)); //清除这一轮的商,为下一轮运算做准备 } } void output() {//从高位到低位逆序输出 int i; for(i = res[0];i >= 1;--i) { printf("%d",res[i]); } printf("\n"); } int main() { scanf("%s",str); change(); solve(); output(); return 0; }当然,这个思路可以推广为“m进制的大数转换为n进制形式“,这就留给你自行思考吧…
本文以上内容转载自http://phinecos.cnblogs.com/
上面是一种通用且普遍的大数进制转换方案,但缺点是写起来较为复杂。
我个人提供一种简易的大数进制转换方案
具有针对性,必须是2^n(n=1,2....)进制间的转换
具体操作是:
将原进制数以二进制数表示并保存,之后在将二进制数按照需要的个数取出依次转换为需要的进制数。比如,16进制转八进制,因为16进制可以用0000-1111进行表示,而八进制数可以以000-111表示,而等价的八进制与等价的16进制在转换为二进制后必定相同,我们可以进行如下转换。
1、将16进制数依次用四个二进制数来表示。
2、依次取用三位二进制数并转换为8进制数。
这样,一个16进制大数就转换为了8进制大数。
原文地址:http://blog.csdn.net/u014492609/article/details/44522267