一. 进制的简介
-
常见进制
- 二进制
- 八进制
- 十进制
- 十六进制
十进制数 二进制数 八进制数 十六进制数 0 0000 0 0 1 0001 1 1 2 0010 2 2 3 0011 3 3 4 0100 4 4 5 0101 5 5 6 0110 6 6 7 0111 7 7 8 1000 10 8 9 1001 11 9 10 1010 12 A 11 1011 13 B 12 1100 14 C 13 1101 15 D 14 1110 16 E 15 1111 17 F -
基数
所谓基数就是在某种数中,允许选用基本数字符号的个数,如R进制的基数为R,能够使用的数字符号个数为R个,即0、1、2、3……R-1,每个位数满R进一。 -
权位
一个数字符号在不同位时,它所代表的数值是不同的。每个数字符号所代表的数值等于该符号值乘以一个数与该数码所在位置有关的常数,这个常数就叫做位权。位权的大小是以基数为底,数字符号所在位置的序号为指数的整数次幂。
性质:1,整数的最低位的权都是1
2,进制数相邻的两位权的比值为R
二. 进制间的相互转化
-
R进制转换为十进制权值展开法
从左向右依次将这个进制的每一位数字符号值乘以该数码所在为值的位权,将所有求得的十进制值求和,所得即为该进制数转换为十进制数的数值。
![](https://i-blog.csdnimg.cn/blog_migrate/bbf61d6ceab9b2fcc2ac81addfd7e0ac.png)
- 十进制数转换为其它进制
- 整数部分的转换
十进制整数部分的转换规则是“除基取余法”,将十进制除以基数R,得到一个商和一个余数,再将商除以R,再次得到一个商和一个余数,重复此过程直到商为0为止。每次所得的余数就是该十进制数转换为R进制所得的数,其中以最后一次取得的余数为最高位,第一次取到的余数为最低位。例: 十进制13 转换 二进制数
![](https://i-blog.csdnimg.cn/blog_migrate/33f03d7439fc13a7ea7872c12d8c24fc.png)
将所得二进制数以最后一次取得的余数为最高位,第一次取到的余数为最低位依次排开
得13(D) = 1101(B)
void reverse_my(char *str);
//10进制转任意进制数(改进版加/**/为原版)
void myitoa(char *str, int n, int radix)
{
int i = 0;
const static char *numOf36 = { "0123456789ABCDEFGHIJKLMOPENRSTUVWXYZ" };
while (n != 0)
{
int tmp = n % radix;
n /= radix;
/*if (tmp >= 10)
{
str[i++] = 'A' + tmp - 10;
}
else {
str[i++] = '0' + tmp;
}*/
str[i++] = numOf36[tmp];
}
str[i] = '\0';
/*for (int j = 0, k = i - 1; j < k; j++, k--)
{
char tmp = str[k];
str[k] = str[j];
str[j] = tmp;
}*/
reverse_my(str);
}
void reverse_my(char *str)
{
char *low = str;
char *high;
for (high = str; *high != '\0'; high++);
high--;
char tmp;
while (low <= high)
{
tmp = *low;
*low = *high;
*high = tmp;
low++;
high--;
}
}
- 小数部分的转换
十进制小数部分的转换规则为“乘基取整法”。用十进制的小数部分乘以基数R,取走其乘积的整数部分之后,余下的小数部分在与R相乘。重复下去,直到余下的小数部分为0或者满足所要求的精度为止。每次所得的整数部分就是所求的R进制小数,将第一次所得整数位高位,最后一次所得整数为最低位。
![](https://i-blog.csdnimg.cn/blog_migrate/3f2b4931bc30d329bfbbb97a904e5ec9.png)
> 将所得二进制第一次所得整数位高位,最后一次所得整数为最低位依次展开
>得0.875(D) = 0.111(B)
- 二进制与八进制、十六进制的转换
- 二进制转换为八进制:
从二进制数的小数点开始,分别向左向右以三位二进制数为一组,将每一组二进制数转换为一位八进制数。当小数部分的最后一组不够三位时,应在后面舔0补足。整数最前一组不够三位,应在前面舔0。 - 二进制转换为十六进制:
与二进制转换为八进制类似,以四位二进制数为一组,每组四位二进制数转换为一位十六进制数。。当小数部分的最后一组不够四位时,应在后面舔0补足。整数最前一组不够四位,应在前面舔0。 - 八进制、十六进制转换为二进制
分别将八进制(十六进制)每一个符号字符写成二进制的格式,即为二进制数。
- 任意进制之间的转行以代码实现
思路:以10进制为中间进制将p进制转行为10进制再转换为q进制。
#include<stdio.h>
#include<ctype.h>
#include<string.h>
#include<stdlib.H >
//最大位数
#define MAX_DIGIT 10010
/*
将当前c进制数转换为十进制数,
所得10进制模p(所得的进制)得所求进制
*/
char Remainder(int *num,int len,int p,int c)
{
int rem1 = 0;
int rem2 = 0;
for (int i = 0; i < len; i++)
{
rem1 = (num[i] + rem2 * c) % p;
num[i] = (num[i] + rem2 * c) / p;
rem2 = rem1;
}
return rem2;
}
int ctoi(int *num, char *str)
{
int len1 = strlen(str);
for (int i = 0; i < len1; i++)
{
if (isalnum(str[i]))
{
num[i] = str[i] - '0';
}
else if (isalpha(str[i]))
{
num[i] = iswlower(str[i]) - 'a' + 10;
}
}
return len1;
}
int RevIntToChar(char *num,int *num2,int len)
{
int i;
for (i = 0; i < len; i++)
{
if (num2[len-i-1] >= 10)
{
num[i] = num2[len-i-1] + 'A' -10;
}
else
{
num[i] = num2[len-i-1] + '0';
}
}
num[i] = '\0';
return len;
}
//思路
//字符型->整数c进制->倒序p进制->正序p进制
// char -> int -> int -> char
void BinaryConversion(char *num, int pre, int cut)
{
int num1[MAX_DIGIT] = { 0 };
int len_int = 0;
int num2[MAX_DIGIT] = { 0 };
int len_rev = 0;
len_int = ctoi(num1, num);
while (true)
{
int flag = true;
num2[len_rev++] = Remainder(num1, len_int, pre, cut);
if (len_rev > MAX_DIGIT) EXIT_FAILURE; //最大位数超出限制停止程序
for (int j = 0; j < len_int; j++)
{
if (num1[j] != 0)
{
flag = false;
break;
}
}
if (flag)
{
break;
}
}
RevIntToChar(num, num2, len_rev);
}
int main()
{
int pre=16;//下一个进制
int cut=8;//当前进制
char num[MAX_DIGIT] = "1234567123456";
int len_str = strlen(num);
if(len_str>MAX_DIGIT) EXIT_FAILURE; //最大位数超出限制停止程序
BinaryConversion(num, pre, cut);
printf("%s", num);
return 0;
}