按照 “先余为低位,后余为高位“这条铁律,其结果为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