欢迎您访问 最编程 本站为您分享编程语言代码,编程技术文章!
您现在的位置是: 首页

快速转换整数与浮点数到任意基数(包括16进制),真的不来试试吗?!

最编程 2024-02-20 22:41:39
...

  在学完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]));