在学完c语言初阶以后,想写一个进制转换其实非常的简单,下面我就来带着大家完成这简单的精制转换。
题目描述:
主题思路:我们将要转换的字符串分为两部分,整数和小数,将他们分别转化为10进制,然后在分别转化为我们想要转化为的进制,因为将任意进制转化为10进制,将10进制转化为任意进制都是我们最熟悉的。
1.主函数
考虑到我们会输入小数点,并且16进制会涉及字母,所以我们用数组C来保存要转换的浮点数,既是用字符串的形式保存。我们将输入的浮点数分为两个部分处理,小数点前后为分界线分开处理我们的浮点数,并用arr数组来存放转化后的字符串。
int main() { int A, B; char C[100], arr[100]; int i = 0; scanf("%d %d %s", &A, &B, C); memset(arr, 0, sizeof(char[100])); //整数部分转换: intreverse(C, arr, A, B); //小数部分转换 doublereverse(C, arr, A, B); }
2.intreverse部分(整数的转换)
A.将小数点之前的(整数)字符串以10进制存入整形sum里面。
首先我们来复习一下所有进制转化为10进制的方法:
基数乘以指数的n次方法 。
基数:进制数值本身(比如二进制数 1010,1010就是基数),
指数:相应的进制值(二进制的指数就是:2,八进制的指数就是:8),n:表示基数的位置,以小数点分割,左边的数从0开始数,右边的数(也就是小数点后面的数)从 -1开始数
代码实现
void intreverse(char C[100], char arr[100], int A, int B) { //转化十进制: int count = 0, sum = 0, l = 0; while (C[count] != '.') { count++; } int i = count - 1, j = 0; while (i > -1) { if (C[i] >= 48 && C[i] <= 57) sum += pow(A, j++) * (C[i--] - 48); else sum += pow(A, j++) * (C[i--] - 87); }
这里需要注意的是我们存进去的是字符串形式,故在存入sum里面时要字符减去相应的ASCII值在进行计算,比如我们存入的字符‘1’,实际是49这个数字代表的,我们要在计算中使用1,就要用49-48才行。同理我们在16进制中使用的abcd,需要减去相应的ASCII(87)把他转化为1到16之间的数字。
B.将整数转化后的10进制转化为目标转化对的进制。
我们再来复习一下10进制转化为其他进制的方法:
对该进制求余法,并反向取余数得到结果,案例如下:
上述:17转换为2进制的结果为: 10001
while (sum) { if ((sum % B) >= 0 && (sum % B) <= 9) { arr[i++] = sum % B + 48; sum /= B; } else { arr[i++] = sum % B + 87; sum /= B; } }
上面要注意的时我们存入的顺序是倒序的,我们需要对他进行逆序。最后在记得把“."加入arr数组内哦。
arr[i] = '.'; int r = --i; while (r > l) { char temp = arr[r]; arr[r--] = arr[l]; arr[l++] = temp; } }
这样我们就把整数的转化完成了。
2.doublerevere部分(小数点部分的转化):
A.将小数点之前的(整数)字符串以10进制存入整形sum里面。
同理我们可以将小数部分转化为浮点型存入浮点型的sum。
void doublereverse(char C[100], char arr[100], int A, int B) { int count = 0,sz; double sum = 0.0; while (C[count++] != '.') { ; } int i = count, j = -1; while (i <= strlen(C) - 1) { if (C[i] >= 48 && C[i] <= 57) sum += pow(A, j--) * (C[i++] - 48); else sum += pow(A, j--) * (C[i++] - 87); }
B.将整数转化后的10进制转化为目标转化对的进制。
对于小数部分与整数相反,10进制转化为其他进制的方法是乘以改进制取整,对于2进制则*2取整对于剩下的小数部分继续*2取整,如此不断重复,直到小数部分为0为止.第一次所得到为最高位,最后一次得到为最低位,对于8进制*8取整,对于16进制乘以16取整,以此类推。
对十进制小数乘2得到的整数部分和小数部分,整数部分既是相应的二进制数码,再用2乘小数部分(之前乘后得到新的小数部分),又得到整数和小数部分.
如:0.5的二进制
0.5*2=1.0 取整是1
即0.5的二进制为 0.1 ( 第一次所得到为最高位,最后一次得到为最低位)
0.8125的二进制
0.8125*2=1.625 取整是1
0.625*2=1.25 取整是1
0.25*2=0.5 取整是0
0.5*2=1.0 取整是1
即0.8125的二进制是0.1101(第一次所得到为最高位,最后一次得到为最低位)
2.
16进制也是这样:
(0.142578125)10 = (0.248)16
0.142578125*16 = 2.28125 取整2
0.28125*16 = 4.5 取整4
0.5*16 = 8.0 取整8
即0.248
count = 0; while (arr[count++] != '.') { ; } if (sum == 0) { arr[count] = '0'; } int ret = count; while (sum!=0) { sz = sum * B; if (sz > 9) { arr[count++] = sz + 87; sum = sum * B - sz; } else { arr[count++] = sz + 48; sum = sum * B - sz; } } }
这里我们将变量sz设为整形,即将小数强转为整形,即为取整操作。
最后我们将他们打印出来就行啦!
for (i = 0; i <ret + 8; i++) { printf("%c", arr[i]); } }
注意:这里我们是保留的8位小数哦!
完整代码:
#include<stdio.h> #include<string.h> #include<math.h> #include<stdlib.h> void intreverse(char C[100], char arr[100], int A, int B) { //转化十进制: int count = 0, sum = 0, l = 0; while (C[count] != '.') { count++; } int i = count - 1, j = 0; while (i > -1) { if (C[i] >= 48 && C[i] <= 57) sum += pow(A, j++) * (C[i--] - 48); else sum += pow(A, j++) * (C[i--] - 87); } i = 0; if (sum == 0) { arr[i++] = '0'; } while (sum) { if ((sum % B) >= 0 && (sum % B) <= 9) { arr[i++] = sum % B + 48; sum /= B; } else { arr[i++] = sum % B + 87; sum /= B; } } arr[i] = '.'; int r = --i; while (r > l) { char temp = arr[r]; arr[r--] = arr[l]; arr[l++] = temp; } } void doublereverse(char C[100], char arr[100], int A, int B) { int count = 0,sz; double sum = 0.0; while (C[count++] != '.') { ; } int i = count, j = -1; while (i <= strlen(C) - 1) { if (C[i] >= 48 && C[i] <= 57) sum += pow(A, j--) * (C[i++] - 48); else sum += pow(A, j--) * (C[i++] - 87); } count = 0; while (arr[count++] != '.') { ; } if (sum == 0) { arr[count] = '0'; } int ret = count; while (sum!=0) { sz = sum * B; if (sz > 9) { arr[count++] = sz + 87; sum = sum * B - sz; } else { arr[count++] = sz + 48; sum = sum * B - sz; } } for (i = 0; i <ret + 8; i++) { printf("%c", arr[i]); } } int main() { int A, B; char C[100], arr[100]; int i = 0; scanf("%d %d %s", &A, &B, C); memset(arr, 0, sizeof(char[100])); intreverse(C, arr, A, B); doublereverse(C, arr, A, B); }
以上就是浮点数进制转换的完整版本,总结一下,就是把输入的进制转化为10进制,再将该10进制转化为我们目标的进制。其中,因为小数部分和整数部分转化的方法不一样,我们将他分为两个部分分开转化。这就是浮点数转化的答题思路,希望对你有帮助哦!写博客不易,如果这篇文章对你有帮助的话一定要点赞并关注我哦!我会和一直和大家分享我的学习心得与感想的!谢谢大家!