免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 2814 | 回复: 0
打印 上一主题 下一主题

一个进制转换程序 [复制链接]

论坛徽章:
1
CU十二周年纪念徽章
日期:2013-10-24 15:41:34
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2011-12-19 22:39 |只看该作者 |倒序浏览


  1. /*
  2. 进制转换,支持二进制,八进制,十进制,16进制, 支持超大数(1000位),目前不支持负数、浮点数(小数)

  3. 这个程序还可以优化,这里是最朴素的实现。对于不是特别大的数和某些转换,可使用标准库函数,比如strtol,sprintf,atoi,printf等
  4. */

  5. #include <stdio.h>
  6. #include <stdlib.h>
  7. #include <string.h>

  8. #define maxhp 1000

  9. typedef struct _HP HP;

  10. struct _HP
  11. {
  12.         int len;
  13.         int s[maxhp];
  14. };

  15. void hp2str(HP x, char *s)
  16. {
  17.         int i;
  18.         for (i = 0; i < x.len; i++)
  19.         {
  20.                 s[i] = x.s[x.len - i] + '0';
  21.         }
  22.         s[i] = 0;
  23. }

  24. void int2hp(int inte, HP *x)
  25. {
  26.         if (inte == 0)
  27.         {
  28.                 x->len = 1;
  29.                 x->s[1] = 0;
  30.                 return;
  31.         }
  32.         for (x->len = 0; inte > 0;)
  33.         {
  34.                 x->s[++x->len] = inte % 10;
  35.                 inte /= 10;
  36.         }
  37. }

  38. /* c=a+b */
  39. void add(const HP a, const HP b, HP *c)
  40. {
  41.         int i;
  42.         c->s[1] = 0;
  43.         for (i = 1; i <= a.len || i <= b.len || c->s[i]; i++)
  44.         {
  45.                 if (i <= a.len)
  46.                         c->s[i] += a.s[i];
  47.                 if (i <= b.len)
  48.                         c->s[i] += b.s[i];
  49.                 c->s[i + 1] = c->s[i] / 10;
  50.                 c->s[i] %= 10;
  51.         }
  52.         c->len = i - 1;
  53.         if (c->len == 0)
  54.                 c->len = 1;
  55. }

  56. /* c=a*b */
  57. void multiply(const HP a, const HP b, HP *c)
  58. {
  59.         int i, j;
  60.         c->len = a.len + b.len;
  61.         for (i = 1; i < c->len; i++)
  62.                 c->s[i] = 0;
  63.         for (i = 1; i <= a.len; i++)
  64.         {
  65.                 for (j = 1; j <= b.len; j++)
  66.                 {
  67.                         c->s[i + j - 1] += a.s[i] * b.s[j];
  68.                 }
  69.         }

  70.         for (i = 1; i < c->len; i++)
  71.         {
  72.                 c->s[i + 1] += c->s[i] / 10;
  73.                 c->s[i] %= 10;
  74.         }

  75.         while (c->s[i])
  76.         {
  77.                 c->s[i + 1] = c->s[i] / 10;
  78.                 c->s[i] %= 10;
  79.                 i++;
  80.         }
  81.         while (i > 1 && !c->s[i])
  82.                 i--;
  83.         c->len = i;
  84. }

  85. /* 将十进制的str除以to ,dest为商,函数返回余数*/
  86. int divto(char *str, int to, char *dest)
  87. {
  88.         int i, j, m,len,len2;
  89.         len = strlen(str);
  90.         m = 0;
  91.         for (i = 0; i < len; i++)
  92.         {
  93.                 m = m * 10 + str[i] - '0';
  94.                 dest[i] = m / to + '0';
  95.                 m %= to;
  96.         }

  97.         j = len;
  98.         for (i = 0; i < len; i++)
  99.                 if (dest[i] - '0')
  100.                 {
  101.                         j = i;
  102.                         break;
  103.                 }
  104.         if (i >= len)
  105.                 {
  106.                         dest[0] = '0';
  107.                         dest[1] = 0;
  108.                         return m;
  109.                 }

  110.         len2 = len - j;
  111.         for (i = 0; i < len2; i++)
  112.                 dest[i] = dest[j++];

  113.         dest[i] = 0;

  114.         return m;
  115. }

  116. /* 将from进制(二进制、八进制、16进制)的str转为10进制*/
  117. void convert2dec(char *str, int from, char *dest)
  118. {

  119.         int i, j, m,len;
  120.         len = strlen(str);
  121.         m = 0;
  122.         /* 二进制转10进制    1010->10
  123.          * 八进制转10进制    031->25 0777->511
  124.          * 16进制转10进制    0xa1->161 0x20->32
  125.          * 输入:str为八进制时,前面的0省略,str为16进制时,0x省略
  126.          */
  127.         HP a, b,c, fm;
  128.         int2hp(m, &a);
  129.         int2hp(from, &fm);
  130.         c = a;
  131.         for (i = 0; i < len; i++)
  132.         {
  133.                 multiply(c, fm, &c);/* c=c*fm*/
  134.                 if (from == 16)
  135.                 {
  136.                         if (str[i] >= 'A' && str[i] <= 'F')
  137.                         {
  138.                                 int2hp(str[i] - 'A' + 10, &b);
  139.                                 add(c, b, &c);
  140.                         }
  141.                         else if (str[i] >= 'a' && str[i] <= 'f')
  142.                         {
  143.                                 int2hp(str[i] - 'a' + 10, &b);
  144.                                 add(c, b, &c);
  145.                         }
  146.                         else
  147.                         {
  148.                                 int2hp(str[i] - '0', &b);
  149.                                 add(c, b, &c);
  150.                         }
  151.                 }
  152.                 else
  153.                 {
  154.                         int2hp(str[i] - '0', &b);
  155.                         add(c, b, &c);
  156.                 }

  157.         }
  158.         hp2str(c, dest);
  159. }

  160. /* 从from进制转为to进制  ,str为八进制时,前面的0省略,str为16进制时,0x省略 ,支持二进制,八进制,十进制,16进制*/
  161. void baseconvert(char *str, int from, char* dest, int to)
  162. {
  163.         int m, i, j;
  164.         char c;
  165.         if (from == to || *str == '0'){

  166.        
  167.                 strcpy(dest, str);
  168.                 return ;
  169.         }

  170.         /* 首先转为10进制*/
  171.         if (from != 10)
  172.         {
  173.                 convert2dec(str, from, dest);
  174.                 if(to==10)return ;
  175.         }
  176.         else
  177.         {
  178.                 strcpy(dest,str);
  179.         }

  180.         char *res = malloc(4 * strlen(dest)+1);

  181.         char *tmp = dest;
  182.         i = 0;

  183.         /*再由10进制转为to进制 */
  184.         while (*tmp - '0')
  185.         {
  186.                 m = divto(tmp, to, dest);
  187.                 res[i] = m + '0';
  188.                 if (m >= 10 && m <= 15)
  189.                         res[i] = m - 10 + 'a';
  190.                 i++;
  191.         }

  192.         for (j = 0, m = i - 1; j < i; j++, m--)
  193.         {
  194.                 dest[j] = res[m];
  195.         }
  196.         dest[j] = 0;
  197.         free(res);
  198. }


  199. int main()
  200. {
  201.                 char str[100];
  202.                 char dest[410];
  203.                 int from,to;
  204.                 while(scanf("%s%d%d",str,&from,&to)!=EOF)/*from进制的str转为to进制*/
  205.                 {

  206.                 /*memset(dest,0,sizeof(dest));*/
  207.                 baseconvert(str,from,dest,to);
  208.                 printf("res=%s\n",dest);
  209.         }
  210. }

复制代码
相关帖子:
http://bbs.chinaunix.net/thread-3629443-1-2.html
http://bbs.chinaunix.net/thread-1342536-1-1.html
http://bbs.chinaunix.net/thread-1315250-1-1.html
http://bbs.chinaunix.net/thread-1300500-1-1.html
http://bbs.chinaunix.net/thread-1239461-1-1.html
http://bbs.chinaunix.net/thread-1229661-1-1.html
http://bbs.chinaunix.net/thread-1468845-1-1.html
http://bbs.chinaunix.net/thread-1738674-1-1.html
http://bbs.chinaunix.net/thread-1823027-1-1.html
http://bbs.chinaunix.net/thread-3622832-1-1.html
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP