今天分享一篇关于C/C++实现任意进制数之间互转的文章,能实现任意进制数转化为任意进制数,细节拉满,相信看完你的C/C++编程能力和思维能力一定会有所提升!
目录
1.整体思路分析
想要实现任意进制数之间互转是不容易的,如果直接一步到位转化的话也能实现,不过这打破了常规思维及其不易理解。所以我给出的方案是:先获取这个数,再将其转化为十进制数,然后再转化为想要转化的进制数。
1.1任意进制数转化为十进制数思路准备
以八进制数为例来分析(其他进制数转换为十进制数原理相同)。
八进制数,逢八进一,数中不会出现数字8。以八进制数76543210为例:
转换结果:=7*8^{7}+6*8^{6}+5*8^{5}+4*8^{4}+3*8^{3}+2*8^{2}+1*8^{1}+0*8^{0}
即:
而在程序中具体实现时需要将算子倒过来,也就是:=0*8^{0}+1*8^{1}+2*8^{2}+3*8^{3}+4*8^{4}+5*8^{5}+6*8^{6}+7*8^{7}
即:
其最终结果为(十进制数):16434824
有了这个基础就能把任意进制数转化为十进制数了。
1.2十进制数转化为任意进制数思路准备
十进制数转其他进制数的方法也有很多,考虑到C/C++程序有取余功能,再结合其整除算法,以下方法也许就是最佳选择:
还是以十进制数16434824转换为八进制数为例。考虑到数16434824 = 0*8^{0} + 1*8^{1} + 2*8^{2} + 3*8^{3} + 4*8^{4} + 5*8^{5} + 6*8^{6} + 7*8^{7}
即:
(以下操作可理解为将上式两边同时进行,若不理解可私信我)
对其取余8得到0,即16434824%8 = 0
除以8得 :16434824/8 = 2054353
对2054353取余8的得:2054353%8=1
除以8得:2054353/8=256794
对256794取余8的得:256794%8=2
除以8得:256794/8=32099
对32099取余8的得:32099%8=3
除以8得:32099/8=4012
对4012取余8的得:4012%8=4
除以8得:4012/8=501
对501取余8的得:501%8=5
除以8得:501/8=62
对62取余8的得:62%8=6
除以8得:62/8=7
对7取余8的得:7%8=7
除以8得:7/8=0,结束。
其中加红部分即为转换结果,即:76543210
按照这个思路就可以把十进制数转换为任意进制数。
有了以上两种转换方法也就能实现任意进制数转换为任意进制数。
2.具体程序设计
2.1准备需要用的函数
在数转化过程中需要用到计算 x^y 的函数,即 pow(x,y);
具体程序段设计如下:
/**
* @brief 计算m的n次幂。
* @param /
* @retval /
*/
int my_pow(int m,int n)
{
if (n == 0)
return 1;
int t = m;
while (--n)
t *= m;
return t;
}
2.2任意进制数转化为十进制数程序设计
转换机制在1.1中已经详细讲了,具体实现程序段如下:
/**
* @brief 把ip进制数num转化为10进制数并输出。
* @param /
* @retval /
*/
int transform_p_10(int ip, char* num)
{
int n = 0, l = 0;
for (int i = 0; num[i]; i++)
l = i + 1;//得到字符串长度,也可以用strlen()函数获取
for (int i = l-1; i+1 ; i--)
{
if ('0' <= num[i] && num[i] <= '9')
n += (num[i] - '0')*my_pow(ip,l-i-1);
if ('a' <= num[i] && num[i] <= 'z')
n += (num[i] - 'a' + 10) * my_pow(ip, l - i - 1);
if ('A' <= num[i] && num[i] <= 'Z')
n += (num[i] - 'A' + 10) * my_pow(ip, l - i - 1);
}
return n;
}
具体也是从字符串的尾部开始,利用字符的ASCII码得到对应的数值,然后计算得出对应的十进制数。
2.3十进制数转化为任意进制数程序设计
转换机制在1.2中已经详细讲了,具体实现程序段如下:
/**
* @brief 把十进制数n转化为op进制数
* @param /
* @retval 无
*/
void transform_10_p(int n, int op, char* transform_out)
{
if (n / op != 0)
transform_10_p(n / op, op, transform_out);
transform_out[transform_t] = (n % op) + (n % op < 10 ? '0' : 'A' - 10);
transform_out[++transform_t] = 0;
}
这里则利用了函数嵌套完成了进制数之间的转化。具体可以理解为:一直对数进行取余,直到被取余数小于取余数,然后一步步计算得出对应进制下对应的数值。
2.4综合调用程序设计
为了方便调用所写的程序,特设计了一个综合调用的子函数,以实现一个函数完成一次任意进制数之间的转换。具体程序段设计如下:
/**
* @brief 进制转换主函数,初始化并调用转换。
* @param 0 < ip <= 9 + 26; 0 < op <= 9 + 26;
* @retval 无
*/
void transform(int ip, char* num, int op, char* transform_out)
{
int n = 0;
transform_t = 0;
n = transform_p_10(ip,num);
transform_10_p(n, op, transform_out);
}
3.整体程序设计
完成上述步骤后,程序也就设计好了,整合后得到的最终程序段如下(方便直接取用):
#include<stdio.h>
#pragma warning (disable:4996)
int transform_t = 0;
int my_pow(int m, int n);
int transform_p_10(int ip, char* n);
void transform_10_p(int n, int op, char* transform_out);
void transform(int ip, char* num, int op, char* transform_out);
int main()
{
int i = 0, o = 0;
char in[30] = "0";
char out[30] = "0";
printf("请输入待转数字(可包含字母):");
scanf("%s", &in);
printf("待转数字的进制数是:");
scanf("%d", &i);
printf("需要输出为几进制数:");
scanf("%d", &o);
transform(i, in, o, out);
printf("转换结果是:%s\n", out);
return 0;
}
/**
* @brief 计算m的n次幂。
* @param /
* @retval /
*/
int my_pow(int m,int n)
{
if (n == 0)
return 1;
int t = m;
while (--n)
t *= m;
return t;
}
/**
* @brief 把ip进制数num转化为10进制数并输出。
* @param /
* @retval /
*/
int transform_p_10(int ip, char* num)
{
int n = 0, l = 0;
for (int i = 0; num[i]; i++)
l = i + 1;
for (int i = l-1; i+1 ; i--)
{
if ('0' <= num[i] && num[i] <= '9')
n += (num[i] - '0')*my_pow(ip,l-i-1);
if ('a' <= num[i] && num[i] <= 'z')
n += (num[i] - 'a' + 10) * my_pow(ip, l - i - 1);
if ('A' <= num[i] && num[i] <= 'Z')
n += (num[i] - 'A' + 10) * my_pow(ip, l - i - 1);
}
return n;
}
/**
* @brief 把十进制数n转化为op进制数
* @param /
* @retval 无
*/
void transform_10_p(int n, int op, char* transform_out)
{
if (n / op != 0)
transform_10_p(n / op, op, transform_out);
transform_out[transform_t] = (n % op) + (n % op < 10 ? '0' : 'A' - 10);
transform_out[++transform_t] = 0;
}
/**
* @brief 进制转换主函数,初始化并调用转换。
* @param 0 < ip <= 9 + 26; 0 < op <= 9 + 26;
* @retval 无
*/
void transform(int ip, char* num, int op, char* transform_out)
{
int n = 0;
transform_t = 0;
n = transform_p_10(ip,num);
transform_10_p(n, op, transform_out);
}
4.结果展示
以程序员计算器计算的结果来验证程序的正确性,以8进制数76543210为例:
将8进制数76543210转为十进制数:
将十进制数16434824转为16进制数:
将16进制数FAC688转为2进制数:
将二进制数111110101100011010001000转为8进制数:
结果又回到了8进制数76543210,达到了闭环,并且与程序员计算器计算的结果保持一致,验证了程序的正确性。
程序可能任然有可以改进的地方。又如,读者可以以此程序为原型,设计任意进制数之间的运算的程序,检验学习的效果(如有需要可联系作者)。如果有任何疑问,都可以来找作者,评论区和私信都欢迎你!
原创文章,感谢支持!