C语言实现任意进制转换代码及解析

栏目: C · 发布时间: 5年前

内容简介:给定一个 M 进制的数 x,实现对 x 向任意的一个非 M 进制的数的转换。掌握不同数制间的转换关系是解决问题的关键,这里所说的数制一般包括二进制、八进制、十六进制及十进制。除了不同的数制还有下面几个必须要了解的概念。基数:在一种数制中,只能使用一组固定的数字来表示数的大小,这组固定的数字的个数就称为该计数制的基数(Base)。例如十进制的基数为10,二进制的基数为2等。

问题描述

给定一个 M 进制的数 x,实现对 x 向任意的一个非 M 进制的数的转换。

问题分析

掌握不同数制间的转换关系是解决问题的关键,这里所说的数制一般包括二进制、八进制、十六进制及十进制。除了不同的数制还有下面几个必须要了解的概念。

基数:在一种数制中,只能使用一组固定的数字来表示数的大小,这组固定的数字的个数就称为该计数制的基数(Base)。例如十进制的基数为10,二进制的基数为2等。

权:又称为位权或权值,即每一个数位都有一个固定的基值与之相对应,称之为权。如十进制的个位对应的权值为1(100),十位对应的权值为10(101),百位对应的权值为100(102)。对于一个 M 进制的数来说,小数点左边各位上对应的权值从右到左分别为基数的0次方、基数的1次方、基数的2次方等,对于小数点右边各位上对应的权值从左到右分别为基数的-1次方、基数的-2次方等。

二进制、八进制、十六进制向十进制转换:按权展开相加。

十进制转换成二进制、八进制、十六进制:整数部分除以基数取余数(取余的方向为从后向前);小数部分乘以基数取整数(取整的方向为从前向后)。

二进制、八进制、十六进制相互转换:先转换成十进制再转换成其他进制;或者按照其对应关系进行转换(三位二进制数对应一位八进制数,四位二进制数对应一位十六进制数)。本例题按照前一种转换方式进行编程。

算法设计

十六进制是由 0~F 这一组固定的数字来表示,所以釆用字符数组进行存储。在进行输入输出时数组元素都是以字符的形式存在的,但是在进行数制转换时数组元素又以数值的形式存在,程序中用两个自定义函数 char_to_number 和 number_to_char 来实现字符与其对应数值之间的转换。

在执行程序时可以输入多组数据来验证程序的正确性,以前的程序都是多次运行,输入不同的数据来实现。对程序稍做改进,只运行一次程序但可以输入多组数据进行验证。解决这个问题只需要加一层循环,如果循环条件为真则继续输入数据,否则退出。循环条件为真即表达式的值不为0,这样可以声明一个变量假设为 flag,利用语句 while(flag){循环体} 来进行控制,当 flag 的值为1时可以接着输入,若为0则结束循环。

下面是完整的代码:

#include <stdio.h>

#define MAXCHAR 101  /*最大允许字符串长度*/

int char_to_num(char ch);  /*返回字符对应的数字*/

char num_to_char(int num);  /*返回数字对应的字符*/

long source_to_decimal(char temp[], int source);  /*返回由原数转换成的10进制数*/

int decimal_to_object(char temp[], long decimal_num, int object);  /*返回转换成目标数制后字符数组的长度*/

void output(char temp[], int length);  /*将字符数组逆序打印*/

int main()

{

int source;  /*存储原数制*/

int object;  /*存储目标数制*/

int length;  /*存储转换成目标数制后字符数组的长度*/

long decimal_num;  /*存储转换成的10进制数*/

char temp[MAXCHAR];  /*存储待转换的数值和转换后的数值*/

int flag = 1;  /*存储是否退出程序的标志*/

while(flag)  /*利用输入的flag值控制循环是否结束*/

{

printf("转换前的数是:");

scanf("%s", temp);

printf("转换前的数制是:");

scanf("%d", &source);

printf("转换后的数制是:");

scanf("%d", &object);

printf("转换后的数是:");

decimal_num = source_to_decimal(temp, source);

length = decimal_to_object(temp, decimal_num, object);

output(temp, length);

printf("继续请输入1,否则输入0:\n");

scanf("%d", &flag);

}

return 0;

}

/*将字符转换成数字*/

int char_to_num(char ch)

{

if(ch>='0' && ch<='9')

return ch-'0';  /*将数字字符转换成数字*/

else

return ch-'A'+10;  /*将字母字符转换成数字*/

}

char num_to_char(int num)

{

if(num>=0 && num<=9)

return (char)('0'+num-0);  /*将0~9之间的数字转换成字符*/

else

return (char)('A'+num-10);  /*将大于10的数字转换成字符*/

}

long source_to_decimal(char temp[], int source)

{

long decimal_num = 0;  /*存储展开之后的和*/

int length;

int i;

for( i=0; temp[i]!='\0'; i++ );

length=i;

for( i=0; i<=length-1; i++ )  /*累加*/

decimal_num = (decimal_num*source) + char_to_num(temp[i]);

return decimal_num;

}

int decimal_to_object(char temp[], long decimal_num, int object)

{

int i=0;

while(decimal_num)

{

temp[i] = num_to_char(decimal_num % object);  /*求出余数并转换为字符*/

decimal_num = decimal_num / object;  /*用十进制数除以基数*/

i++;

}

temp[i]='\0';

return i;

}

void output(char temp[], int length)

{

int i;

for( i=length-1; i>=0; i--)  /*输出temp数组中的值*/

printf("%c", temp[i]);

printf("\n");

}

运行结果:

转换前的数是:17

转换前的数制是:10

转换后的数制是:2

转换后的数是:10001

继续请输入1,否则输入0:

1

转换前的数是:17

转换前的数制是:10

转换后的数制是:8

转换后的数是:21

继续请输入1,否则输入0:

1

转换前的数是:17

转换前的数制是:10

转换后的数制是:16

转换后的数是:11

继续请输入1,否则输入0:

1

转换前的数是:12122

转换前的数制是:8

转换后的数制是:10

转换后的数是:5202

继续请输入1,否则输入0:

0

C语言实现任意进制转换代码及解析

Linux公社的RSS地址https://www.linuxidc.com/rssFeed.aspx

本文永久更新链接地址: https://www.linuxidc.com/Linux/2018-12/155754.htm


以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

重启

重启

米奇•乔尔 / 曲强 / 中信出版社 / 2014-6-10 / 45.00元

罗振宇、丹尼尔•平克、赛斯•高汀、丹•艾瑞里、谢家华、阿里安娜•赫芬顿强烈推荐! 美国亚马逊2013年年度商业&投资类图书榜前20名! 互联网时代五大剧变让企业和个人无处可逃 进化,或被扔在旧时代? 全球顶尖的数字预言家独特分享 商业转型与思维转型的实践指南 当个人变为互联世界中的一个节点,如何开启新的工作方式? 如何与顾客建立直接关系?如何进行实用主义营......一起来看看 《重启》 这本书的介绍吧!

图片转BASE64编码
图片转BASE64编码

在线图片转Base64编码工具

Base64 编码/解码
Base64 编码/解码

Base64 编码/解码

HEX CMYK 转换工具
HEX CMYK 转换工具

HEX CMYK 互转工具