zoukankan      html  css  js  c++  java
  • 大数加减乘以及高精度幂

    我们都知道int, long, long long 等数据类型,但是如果一个数字过长的话,这些数据所定义的变量就放不下了,这时就要用到大数,所谓大数,就是比较大的数,超出了我们平时long long所定义的范围,这时可以用数组将它存放起来,用模拟手算的方式来让计算机计算,下面试关于大数的加减乘及高精度幂的代码实现

      1 #include <stdio.h>
      2 #include <stdlib.h>
      3 #include <string.h>
      4 #define NUM 10001//定义数组长度
      5 void showmeau();
      6 void change(char *ch1, char *ch2);
      7 void add(char *ch1, char *ch2);
      8 void sub(char *ch1, char *ch2);
      9 void Input();
     10 void add_big_number();
     11 void sub_big_number();
     12 void multi(char *ch1, char *ch2);
     13 void multi_big_number();
     14 void exchange(char *ch, int *count);
     15 void multi_power(char *ch, int n, int count);
     16 void high_precision_power();
     17 
     18 char s1[NUM], s2[NUM]; int n, flag = 0;
     19 int main()
     20 {
     21     showmeau();
     22     return 0;
     23 }
     24 void showmeau()
     25 {
     26     do{
     27         system("cls");//调用系统命令清屏
     28         printf("1. big number add  2. big number sub   
    3.big number multi  4. High precision power  
    		0. exit
    ");
     29         scanf("%d", &n);
     30         switch(n)
     31         {
     32         case 1:
     33             add_big_number();
     34             break;
     35         case 2:
     36             sub_big_number();
     37             break;
     38         case 3:
     39             multi_big_number();
     40             break;
     41         case 4:
     42             high_precision_power();
     43             break;
     44         case 0:
     45             break;
     46         default:
     47             printf("your input error!
    ");
     48             break;
     49         }
     50         system("pause");
     51     }while(n != 0);
     52 
     53 }
     54 
     55 void Input()
     56 {
     57     printf("Input the first big number:
    ");
     58     scanf("%s", s1);
     59     printf("Input the second big number:
    ");
     60     scanf("%s", s2);
     61 }
     62 void change(char *ch1, char *ch2)//去掉负号函数
     63 {
     64     int len1 = strlen(ch1), len2 = strlen(ch2);
     65     int i;
     66     char str1[NUM], str2[NUM];
     67     switch(flag)
     68     {
     69     case 1:
     70         for(i = 0; i < len1 - 1; i ++)//如果都是负数的时候执行到ch1[1];
     71             str1[i] = ch1[len1 - i - 1];
     72         str1[i] = '';
     73         for(i = 0; i < len2 - 1; i ++)
     74             str2[i] = ch2[len2 - i - 1];
     75         str2[i] = '';
     76         break;
     77     case 2:
     78         for(i = 0; i < len1 - 1; i ++)//如果一正一负的话
     79             str1[i] = ch1[len1 - i - 1];
     80         str1[i] = '';
     81         for(i = 0; i < len2; i ++)
     82             str2[i] = ch2[len2 - i - 1];
     83         str2[i] = '';
     84         break;
     85     case 3:
     86         for(i = 0; i < len1; i ++)//如果一正一负的话
     87             str1[i] = ch1[len1 - i - 1];
     88         str1[i] = '';
     89         for(i = 0; i < len2 - 1; i ++)
     90             str2[i] = ch2[len2 - i - 1];
     91         str2[i] = '';
     92         break;
     93     case 4://如果都是正的
     94         for(i = 0; i < len1; i ++)
     95             str1[i] = ch1[len1 - i - 1];
     96         str1[i] = '';
     97         for(i = 0; i < len2; i ++){
     98             str2[i] = ch2[len2 - i - 1];
     99         }
    100         str2[i] = '';
    101         break;
    102     default:
    103         break;
    104     }
    105     memset(ch1, 0, sizeof(ch1));//将ch1清空
    106     memset(ch2, 0, sizeof(ch2));//将ch2清空
    107     strcpy(ch1, str1);
    108     strcpy(ch2, str2);
    109 }
    110 void add(char *ch1, char *ch2)//执行加法过程
    111 {
    112     int len1 = strlen(ch1), len2 = strlen(ch2);
    113     int t = 0, j;//t为进位;
    114     int num[NUM] = {0}, i;
    115     int max = len1 > len2 ? len1 : len2;//找出最大的长度来进行确定循环次数
    116     for(i = 0; i < max; i ++)
    117     {
    118         if(len1 <= i)
    119         {
    120             if(ch2[i] + t - '0' > 9)//这是一位一位的进,
    121             {
    122                 num[i] = ch2[i] - '0' + t - 10;//只保存最后一位
    123                 t = 1;
    124             }
    125             else
    126             {
    127                 num[i] = ch2[i] - '0' + t;
    128                 t = 0;
    129             }
    130             continue;
    131         }
    132         else if(len2 <= i)
    133         {
    134             if(ch1[i] + t - '0' > 9)
    135             {
    136                 num[i] = ch1[i] - '0' + t - 10;
    137                 t = 1;
    138             }
    139             else
    140             {
    141                 num[i] = ch1[i] - '0' + t;
    142                 t = 0;
    143             }
    144             continue;
    145         }
    146         if(ch1[i] - '0' + ch2[i] - '0' + t > 9)
    147         {
    148             num[i] = ch1[i] + ch2[i] + t - '0' - '0' - 10;
    149             t = 1;
    150         }
    151         else
    152         {
    153             num[i] = ch1[i] + ch2[i] + t - '0' - '0';
    154             t = 0;
    155         }
    156     }
    157     if(t == 1)
    158         num[i] = 1;
    159     if(num[i] == 1)
    160         j = i;
    161     else
    162         j = i - 1;
    163     for(; j >= 0; j --)
    164         printf("%d", num[j]);
    165     printf("
    ");
    166 }
    167 void sub(char *ch1, char *ch2)//减法过程函数
    168 {
    169     char ch[NUM]; int num[NUM] = {0};
    170     memset(ch, 0, sizeof(ch));
    171     int flag = 0, i, j; char str1[NUM], str2[NUM];
    172     int len1 = strlen(ch1), len2 = strlen(ch2);
    173     if(len1 < len2)//判断两个数的大小,大的在前
    174     {
    175         strcpy(ch, ch1);
    176         strcpy(ch1, ch2);
    177         strcpy(ch2, ch);
    178         flag = 1;//如果交换了,则说明前面的小,所以最后一定是负数
    179     }
    180     else if(len1 == len2)//当他们等长时,在比较究竟谁大一点
    181     {
    182         for(i = 0; i < len1; i ++)
    183             str1[i] = ch1[len1 - i - 1];
    184         str1[i] = '';
    185         for(i = 0; i < len2; i ++)
    186             str2[i] = ch2[len2 - i - 1];
    187         str2[i] = '';
    188         if(strcmp(str1, str2) < 0)
    189         {
    190             strcpy(ch, ch1);
    191             strcpy(ch1, ch2);
    192             strcpy(ch2, ch);
    193             flag = 1;
    194         }
    195     }
    196     len1 = strlen(ch1); len2 = strlen(ch2);
    197     int t = 0;//定义借位
    198     for(i = 0; i < len1; i ++)
    199     {
    200         if(len2 <= i)
    201         {
    202             if(ch1[i] - '0' + t < 0)
    203             {
    204                 num[i] = 10 + ch1[i] - '0' + t;
    205                 t = -1;
    206             }
    207             else
    208             {
    209                 num[i] = ch1[i] - '0' + t;
    210                 t = 0;
    211             }
    212             continue;
    213         }
    214         if(ch1[i] + t < ch2[i])
    215         {
    216             num[i] = 10 + ch1[i] - ch2[i] + t;
    217             t = -1;
    218         }
    219         else
    220         {
    221             num[i] = ch1[i] - ch2[i] + t;
    222             t = 0;
    223         }
    224     }
    225     if(flag)
    226         printf("-");//如果交换了,说明第一个数小于第二个数,要打印负号
    227     for(i = len1; i >= 0; i --)//这里判断第一个数不为零的下标
    228         if(num[i] != 0)
    229             break;
    230     if(i == -1)
    231         printf("0");
    232     for(j = i; j >= 0; j --)//从这个不为零的下标开始打印
    233         printf("%d", num[j]);
    234     printf("
    ");
    235 }
    236 void multi(char *ch1, char *ch2)//乘法函数
    237 {
    238     int len1 = strlen(ch1), len2 = strlen(ch2);
    239     int num[NUM] = {0}, i, j;
    240     for(i = 0; i < len1; i ++)
    241     {
    242         for(j = 0; j < len2; j ++)
    243         {
    244             num[i + j] += (ch1[i] - '0') * (ch2[j] - '0');//先将各个数的乘积保存到int型变量数组中,即num中,然后最后在进行进位
    245         }
    246     }
    247     int t = 0, tmp;//临时变量来保存num + t 的值,因为一计算num[i],num就变啦
    248     for(i = 0; i < len1 + len2 - 1; i ++)
    249     {
    250         if(num[i] + t > 9)
    251         {
    252             tmp = num[i] + t;
    253             num[i] = (t + num[i]) % 10;
    254             t = tmp / 10;//t用来保存进位
    255 
    256         }
    257         else
    258         {
    259             num[i] += t;
    260             t = 0;
    261         }
    262     }
    263     while(t > 9)//如果最后一位不为零,说明有进位
    264     {
    265         num[i ++] = t % 10;
    266         t = t / 10;
    267     }
    268     if(t != 0)
    269         num[i] = t;
    270     if(num[i] != 0)
    271         j = i;
    272     else
    273         j = i - 1;
    274     for(; j >= 0; j --)
    275         printf("%d", num[j]);
    276     printf("
    ");
    277 
    278 }
    279 void exchange(char *ch, int *count)//逆置函数
    280 {
    281     int len = strlen(ch), i, j;
    282     char str[NUM];
    283     j = 0;
    284     for(i = len -1; i >= 0; i --)//判断如果后面有多余的零, 清除掉
    285     {
    286         if(ch[i] == '0')
    287         {
    288             len --;
    289         }
    290         else
    291             break;
    292     }
    293     for(; i >= 0; i --)
    294     {
    295         if(ch[i] == '.')//当读到点的时候,这时记录小数点位数,将它存入count中
    296         {
    297             *count = len - i - 1;
    298             continue;
    299         }
    300         str[j++] = ch[i];
    301     }
    302     str[j] = '';//字符串结束符
    303     strcpy(ch, str);
    304 }
    305 void multi_power(char *ch, int n, int count)
    306 {
    307     int i, j, k, y; char ch1[NUM], ch2[NUM];//ch1用来存放计算时的第一个数,ch2用来存放临时结果
    308     memset(ch1, 0, sizeof(ch1));
    309     memset(ch2, 0, sizeof(ch2));
    310     strcpy(ch1, ch); int t = 0;
    311     for(i = 1; i < n; i ++)//一共循环n-1次
    312     {
    313 
    314         for(j = 0; j < strlen(ch); j ++)//执行大数加法运算,这时的数已经没有小数点了
    315         {
    316             t = 0; int tmp = 0;
    317             for(k = 0; k < strlen(ch1); k ++)
    318             {
    319                 ch2[j + k] += (ch[j] - '0') * (ch1[k] - '0');//将它存入ch2中
    320                 if(ch2[j + k] + t > 9)//判断是否满足进位,此时存入的是ascii码
    321                 {
    322                     tmp = ch2[j + k] + t;
    323                     ch2[j + k] = (ch2[j + k] + t) % 10;
    324                     t = tmp / 10;
    325                 }
    326                 else
    327                 {
    328                     ch2[j + k] += t;
    329                     t = 0;
    330                 }
    331             }
    332             y = j + k;
    333             while(t > 9)//判断到最后还有没有进位
    334             {
    335                 ch2[y ++] = t % 10;
    336                 t /= 10;
    337             }
    338             if(t != 0)//最后一个进位
    339                 ch2[y++] = t;
    340         }
    341         ch2[y] = '';//结束符
    342         memset(ch1, 0, sizeof(ch1));//将ch1清空
    343         int x;
    344         for(x = 0; x < y; x ++)
    345         {
    346             ch2[x] += '0';//将ascii转化成字符123...
    347         }
    348         strcpy(ch1, ch2);
    349         memset(ch2, 0, sizeof(ch2));
    350     }
    351     int flag = 0;
    352     for(i = strlen(ch1) - 1; i >= 0; i --)//打印出来结果
    353     {
    354         if(i == n * count - 1)
    355         {
    356             printf(".");
    357             flag = 1;
    358         }
    359         if(flag)
    360         {
    361             if(ch1[i] == 0)
    362                 continue;
    363         }
    364         printf("%c", ch1[i]);
    365     }
    366     printf("
    ");
    367 }
    368 void add_big_number()
    369 {
    370     Input();
    371     if(s1[0] == '-' && s2[0] == '-')//如果两个数都为负数
    372         flag = 1;
    373     else if(s1[0] == '-' && s2[0] != '-')//如果一正一负
    374         flag = 2;
    375     else if(s1[0] != '-' && s2[0] == '-')//如果一正一负
    376         flag = 3;
    377     else//如果全为正
    378         flag = 4;
    379     change(s1, s2);//调用交换函数,将它们调整好顺序,去掉负号,并且将字符串逆序
    380     switch(flag)
    381     {
    382     case 1:
    383         printf("-");
    384         add(s1, s2);//调用加法函数输出结果
    385         break;
    386     case 2:
    387         sub(s2, s1);//调用减法函数来计算结果并将其输出
    388         break;
    389     case 3:
    390         sub(s1, s2);//调用减法函数来计算结果并将其输出
    391         break;
    392     case 4:
    393         add(s1, s2);//调用加法函数输出结果
    394         break;
    395     }
    396 }
    397 
    398 void sub_big_number()
    399 {
    400     Input();
    401     if(s1[0] == '-' && s2[0] == '-')//如果两个数都为负数
    402         flag = 1;
    403     else if(s1[0] == '-' && s2[0] != '-')//如果一正一负
    404         flag = 2;
    405     else if(s1[0] != '-' && s2[0] == '-')//如果一正一负
    406         flag = 3;
    407     else//如果全为正
    408         flag = 4;
    409     change(s1, s2);//调用交换函数,将它们调整好顺序,去掉负号,并且将字符串逆序
    410     switch(flag)
    411     {
    412     case 1:
    413         sub(s2, s1);//调用减法函数输出结果
    414         break;
    415     case 2:
    416         printf("-");
    417         add(s1, s2);//调用加法函数来计算结果并将其输出
    418         break;
    419     case 3:
    420         add(s1, s2);//调用加法函数来计算结果并将其输出
    421         break;
    422     case 4:
    423         sub(s1, s2);//调用减法函数输出结果
    424         break;
    425     }
    426 }
    427 void multi_big_number()
    428 {
    429     Input();
    430     if(s1[0] == '-' && s2[0] == '-')//如果两个数都为负数
    431         flag = 1;
    432     else if(s1[0] == '-' && s2[0] != '-')//如果一正一负
    433         flag = 2;
    434     else if(s1[0] != '-' && s2[0] == '-')//如果一正一负
    435         flag = 3;
    436     else//如果全为正
    437         flag = 4;
    438     change(s1, s2);
    439     if(flag == 2 || flag == 3)
    440         printf("-");
    441     multi(s1, s2);
    442 }
    443 void high_precision_power()
    444 {
    445     int n, count = 0;
    446     printf("Input the high precision power number:
    ");
    447     scanf("%s", s1);
    448     printf("Input the power number:
    ");
    449     scanf("%d", &n);
    450     exchange(s1, &count);
    451     multi_power(s1, n, count);
    452 }
  • 相关阅读:
    biji001
    公司内部openStack环境信息
    def
    CI调试
    一:Java之面向对象基本概念
    STL_算法_Heap算法(堆排)(精)
    IOS开发-经常使用站点集合
    【iOS开发-47】怎样下载iOS 7.1 Simulator 以及iOS 8离线的Documentation这些文件?
    设计模式简介
    how to deal with &quot;no such file error or diretory&quot; error for a new programmer in QT creator
  • 原文地址:https://www.cnblogs.com/Howe-Young/p/3927593.html
Copyright © 2011-2022 走看看