数制转换(基于长除法的实现)

本文介绍了如何使用长除法处理大整数的数制转换问题,通过递归实现对每位数字的处理,以及长除法在高精度运算和大整数除法中的应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

从二进制的转换出发

在之前的学习中我们已经掌握了十进制转化为二进制的方法,那便是“除2求余,逆序排列”的方法

 实际上,对于其他数制的转化同样也可以采取类似的方法,只需重复求余后逆序排列的过程

实际处理中的问题

在我们进行编程时自然而然的想要使用这种方法来处理数制的转换,但是我们面对一些非常大的数字时似乎这个方法有点行不通了,就像114514114514114514这样的数据,其数位过长了之后已经无法直接使用long long等数据类型来进行储存与运算,只能通过数组来储存数据,为了解决这个问题,我们可以使用长除法。

长除法 

让我们以一个最基础的除法为例

 我们可以看到,在实际进行运算时,我们是对各位上的数字处理的。

以第一步为例子:4除以12商0余4,那么这个余数4就留给下一位,即4乘10加5,然后我们对45进行处理,45除以12商3余9,接下来9留下得到96,96除以12商8余0,此时所有数位我们都已处理完毕,这时的余数0就是456除以12的余数。

通过这样的观察,由于是对各位上的数字进行处理的特点,其可以很好的与数组结合。

//使用mod来表示上一位留下的余数,a[i]为数位上的数字,base为除数
a[i]=a[i]+mod*10;
mod=a[i]%base;

通过这样的结构,我们就实现了对各位数字的处理。

数制转换 

既然我们实现了大整数的除法,那么以除法为核心的模n求余自然就不是问题,只需要利用长除法进行迭代得到最后的结果。

#include <stdio.h>
#include <string.h>
  
int BASE; //数制的基
int DLEN; //待转数的长度
/*
进制转换递归函数:返回值,转换后的长度
【参数说明】
code: 存放转换结果的数组
a: 存放待转数的数组,a[0] 为最高位
k: 转换过程中,余数在code中的位置,从0开始
*/
//
int transform(int code[], int a[], int k)
{     
   int i; //在两个循环中使用
   for (i = 0; i < DLEN; i++)
   {//找到第1个非0数位  
       if (a[i] != 0)
       {
          break;
       }
   }
    
   if(i==DLEN) return k; //求余结束
   / 
    
   int _mod = 0;//余数初值, 即算第i位商时,第i-1位的余数。

    while(i<DLEN)
    {
        a[i]=a[i]+_mod*10;
        _mod=a[i]%BASE;
        a[i]=a[i]/BASE;
        i++;
    }

   code[k] = _mod; //得到一位
      
   return transform(code, a, k + 1); //继续求余
}
  
int main()
{
   char str[321] = {0};
   int nCode[1101] = {0}, nStr[321] = {0};
 
   gets(str);
   DLEN = strlen(str);
 
   scanf("%d", &BASE);
   for (int i = 0; i < DLEN; i++)
   {
       nStr[i] = str[i] - '0';
   }
 
   int codeLen = transform(nCode, nStr, 0);
   for (int i = codeLen - 1; i >= 0; i--)
   {
       printf("%d", nCode[i]);
   }

   return 0;
}

拓展:长除法的应用

除此以外,长除法显然可以应用于高精度运算,大整数除法等。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值