鱼C论坛

 找回密码
 立即注册
查看: 990|回复: 6

[已解决]求解一道题目有关循环及数组问题

[复制链接]
发表于 2020-11-8 11:53:43 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
本帖最后由 ckh020303 于 2020-11-8 16:11 编辑

eaf7527729d46adccd3d865a218a1b3.jpg
我写出来的答案是这样的:
#include <stdio.h>

int main()
{
        long long int a, n, i = 1, sn = 0,tn = 0;
        
        while(scanf("%lld %lld", &n, &a) != EOF)   //多组数据,循环输入并带入n,a;
        {
            while(i<=n)
                {
                        tn = tn + a;
                        sn = sn + tn;                           //当a = 1时,大致为:1 + (10 +1) + (100 +11) + (1000 + 111)……
                        a = a * 10;
                        ++i;
                }
                printf("%lf\n", sn);
                sn = 0;                                         //归零,不与下次结果冲突
                i = 1;                                           //同上
                tn = 0;
        }
        
        return 0;
}
这个答案在n取值比较小的时候成立,但是n可以取到1000,也就是要输出1000位数;
我想到了用数组来求解,把这个输出的数字,按照个位十位等等用数组来表示输出,但是我不会实践,所以请各位鱼友来帮帮我,教我如何用数组来表示每一位数,最好有注释表明,谢谢!

我想要了解的是可不可以把一个很大位数的数,每一位数用一个数组来表示,举例如下:就如2147483647   
                     a[0]表示个位的7
                     a[1]表示十位的4
                     a[2]表示百位的6
                     .....以此类推
最佳答案
2020-11-9 10:08:37
大整数的加减乘除都有。

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>

  4. /***********************************************************************************
  5. 用整形数组解决大数高精度计算问题
  6. 32位系统下 unsigned int 最大存储的数为:4294967296
  7. 为了防止最高位为1导致负数的问题,数组中每个元素最大只存储 999999999
  8. 为了解决溢出问题,在做乘法和除法的时候用到了内嵌汇编,某些编译器可能不支持
  9. ***********************************************************************************/
  10. #define BASE        (1000000000)
  11. #define        NUM_LEN        (9)
  12. #define IS_INITED(p)        ((p->_num != 0) && (p->_initFlag == 0))

  13. //定义一个结构体来存储大整数
  14. typedef struct tagNumeric
  15. {
  16.         //存储大数的数组
  17.         int * _num;
  18.         //为数组分配的内存大小,以 int 为单位,计算字节数则为:_size * sizeof(int)
  19.         int _size;
  20.         //大数的长度,即数组中的有用长度
  21.         int _len;
  22.         //结构体初始化标记
  23.         //鉴于某些编译器初始化变量,某些编译器不初始化变量
  24.         //因此,认为 _initFlag == 0 && _num != 0 时,结构体被初始化
  25.         int _initFlag;
  26. }NUMERIC,*LPNUMERIC;

  27. //初始化大整数结构体,为数组分配内存
  28. int InitNumeric(LPNUMERIC pNum,int size)
  29. {
  30.         int nRet = 0;
  31.         do
  32.         {
  33.                 if(IS_INITED(pNum))
  34.                 {
  35.                         break;
  36.                 }

  37.                 pNum->_num = (int *)malloc(size * sizeof(int));
  38.                 if(pNum->_num == 0)
  39.                 {
  40.                         break;
  41.                 }

  42.                 memset(pNum->_num,0,size*sizeof(int));

  43.                 pNum->_len = 0;
  44.                 pNum->_initFlag = 0;
  45.                 pNum->_size = size;

  46.                 nRet = 1;
  47.         }while(0);

  48.         return nRet;
  49. }

  50. //当分配的内存不足以存储大整数时,为之重新分配内存
  51. //建议为防止内存频繁地被重新分配,可以在初始化时分配大一点
  52. int ReinitNumeric(LPNUMERIC pNum,int size)
  53. {
  54.         int nRet = 0;
  55.        
  56.         do
  57.         {
  58.                 if(!IS_INITED(pNum))
  59.                 {
  60.                         break;
  61.                 }
  62.                
  63.                 if(size <= pNum->_size)
  64.                 {
  65.                         break;
  66.                 }
  67.                
  68.                 pNum->_num = (int *)realloc(pNum->_num,size*sizeof(int));

  69.                 if(pNum->_num == 0)
  70.                 {
  71.                         break;
  72.                 }

  73.                 memset(pNum->_num + pNum->_size,0,(size - pNum->_size)*sizeof(int));
  74.                 pNum->_size = size;

  75.                 nRet = 1;
  76.         }while(0);
  77.        
  78.         return nRet;
  79. }

  80. //释放内存
  81. void UninitNumeric(LPNUMERIC pNum)
  82. {
  83.         if(IS_INITED(pNum))
  84.         {
  85.                 free(pNum->_num);
  86.                 pNum->_num = 0;
  87.         }
  88. }

  89. //给结构体一个初始整数值,这个值必须小于 1000000000
  90. int SetNumber(LPNUMERIC pNum,int number)
  91. {
  92.         int nRet = 0;
  93.        
  94.         do
  95.         {
  96.                 if(number >= BASE)
  97.                 {
  98.                         break;
  99.                 }

  100.                 if(!IS_INITED(pNum) && InitNumeric(pNum,1)==0)
  101.                 {
  102.                         break;
  103.                 }
  104.                
  105.                 pNum->_num[0] = number;
  106.                 pNum->_len = 1;

  107.                 nRet = 1;
  108.         }while(0);

  109.         return nRet;
  110. }

  111. //当需要给结构体一个大于999999999的初始值时,
  112. //可以用字符串形式给它赋值,实例如下:
  113. /*
  114.         NUMERIC num;
  115.         SetNumeric(&num,"1234567890987654321");
  116. */
  117. int SetNumeric(LPNUMERIC pNum,char * number)
  118. {
  119.         int i = 0;
  120.         int nRet = 0;
  121.         char cByte = 0;
  122.         int value = 0;
  123.         int power = 0;
  124.         int index =0;
  125.         int nLen = strlen(number);
  126.         int size = nLen / NUM_LEN + (nLen % NUM_LEN == 0 ? 0 : 1);
  127.        
  128.        
  129.         do
  130.         {
  131.                 if(nLen == 0)
  132.                 {
  133.                         break;
  134.                 }
  135.                
  136.                 if(!IS_INITED(pNum) && InitNumeric(pNum,size) == 0)
  137.                 {
  138.                         break;
  139.                 }

  140.                 if(size > pNum->_size && ReinitNumeric(pNum,size) == 0)
  141.                 {
  142.                         break;
  143.                 }
  144.                
  145.                 for(i=0 ; i<nLen ; i++)
  146.                 {
  147.                         if(number[i]<'0' || number[i]>'9')
  148.                         {
  149.                                 break;
  150.                         }
  151.                 }
  152.                 if(i < nLen--)
  153.                 {
  154.                         break;
  155.                 }


  156.                 for(i=nLen ; i>=0 ; i--)
  157.                 {
  158.                         if((nLen - i) % NUM_LEN == 0)
  159.                         {
  160.                                 if(nLen - i != 0)
  161.                                 {
  162.                                         pNum->_num[index++] = value;
  163.                                 }

  164.                                 value = 0;
  165.                                 power = 1;
  166.                         }
  167.                         cByte = number[i] - 0x30;
  168.                         value += power * cByte;
  169.                         power *= 10;
  170.                 }

  171.                 if(value != 0)
  172.                 {
  173.                         pNum->_num[index++] = value;
  174.                 }

  175.                 pNum->_len = index;               
  176.                 nRet = 1;
  177.         }while(0);

  178.         return nRet;
  179. }

  180. //将大整数转化成字符串,以便于输出。
  181. //当 number 指针传 0 时,函数将返回转化成字符串所需要的内存空间
  182. //实例如下:
  183. /*
  184.         int len =0;
  185.         char * buffer;
  186.         NUMERIC num;
  187.         SetNumeric(&num,"12345678909876543121");
  188.         len = Number2String(&num,0);
  189.         buffer = (char *)malloc(len);
  190.         Number2String(&num,buffer);

  191. */
  192. int Number2String(LPNUMERIC pNum,char * number)
  193. {
  194.         int i = 0;
  195.         int nRet = 0;
  196.         char buffer[16] = {0};
  197.        
  198.         do
  199.         {
  200.                 if(!IS_INITED(pNum))
  201.                 {
  202.                         break;
  203.                 }

  204.                 if(number == 0)
  205.                 {
  206.                         nRet = pNum->_len * NUM_LEN + 1;
  207.                         break;
  208.                 }

  209.                 number[0] = 0;
  210.                
  211.                 for(i=pNum->_len-1 ; i>=0 ; i--)
  212.                 {
  213.                         if(i == pNum->_len-1)
  214.                         {
  215.                                 sprintf(buffer,"%d",pNum->_num[i]);
  216.                         }
  217.                         else
  218.                         {
  219.                                 sprintf(buffer,"%09d",pNum->_num[i]);
  220.                         }
  221.                         strcat(number,buffer);
  222.                 }

  223.                 nRet = strlen(number);
  224.         }while(0);

  225.         return nRet;
  226. }

  227. //大整数与一个 int 相加
  228. int AddNumber(LPNUMERIC pNum,int number)
  229. {
  230.         int i;
  231.         int nRet = 0;
  232.         int carry = 0;
  233.         unsigned int value = 0;
  234.        
  235.         do
  236.         {
  237.                 if(!IS_INITED(pNum))
  238.                 {
  239.                         break;
  240.                 }
  241.                
  242.                 if(pNum->_size == pNum->_len && ReinitNumeric(pNum,pNum->_size + 1) == 0)
  243.                 {
  244.                         break;
  245.                 }
  246.                                
  247.                 for(i=0 ; i<pNum->_len ; i++)
  248.                 {
  249.                         value = pNum->_num[i] + number + carry;
  250.                         pNum->_num[i] = value % BASE;
  251.                         carry = value / BASE;
  252.                 }
  253.                
  254.                 if(carry != 0)
  255.                 {
  256.                         pNum->_num[i++] = carry;
  257.                 }
  258.                 pNum->_len = i;
  259.                
  260.                 nRet = 1;
  261.         }while(0);
  262.        
  263.         return nRet;       
  264. }

  265. //大整数加另外一个大整数
  266. int AddNumeric(LPNUMERIC pNum,LPNUMERIC pAdd)
  267. {
  268.         int i;
  269.         int nRet = 0;
  270.         int carry = 0;
  271.         int size = 0;
  272.         unsigned int value = 0;
  273.        
  274.         do
  275.         {
  276.                 if(!IS_INITED(pNum) || !IS_INITED(pAdd))
  277.                 {
  278.                         break;
  279.                 }
  280.                
  281.                 if(pNum->_size < pAdd->_len)
  282.                 {
  283.                         size = pAdd->_len + 1;
  284.                 }
  285.                 else if(pNum->_size == pNum->_len)
  286.                 {
  287.                         size = pNum->_size + 1;
  288.                 }

  289.                 if(size != 0 && ReinitNumeric(pNum,size) == 0)
  290.                 {
  291.                         break;
  292.                 }
  293.                
  294.                 size = pNum->_len > pAdd->_len ? pNum->_len : pAdd->_len;

  295.                 for(i=0 ; i<size ; i++)
  296.                 {
  297.                         value = carry;

  298.                         if(i < pNum->_len)
  299.                         {
  300.                                 value += pNum->_num[i];
  301.                         }

  302.                         if(i < pAdd->_len)
  303.                         {
  304.                                 value += pAdd->_num[i];
  305.                         }

  306.                         pNum->_num[i] = value % BASE;
  307.                         carry = value / BASE;
  308.                 }
  309.                
  310.                 if(carry != 0)
  311.                 {
  312.                         pNum->_num[i++] = carry;
  313.                 }
  314.                 pNum->_len = i;
  315.                
  316.                 nRet = 1;
  317.         }while(0);
  318.        
  319.         return nRet;       
  320. }

  321. //大整数与一个 int 相乘
  322. int MulNumber(LPNUMERIC pNum,int number)
  323. {
  324.         int i;
  325.         int nRet = 0;
  326.         int carry = 0;
  327.         int * plong = 0;

  328.         do
  329.         {
  330.                 if(!IS_INITED(pNum))
  331.                 {
  332.                         break;
  333.                 }

  334.                 if(pNum->_size == pNum->_len && ReinitNumeric(pNum,pNum->_size + 1) == 0)
  335.                 {
  336.                         break;
  337.                 }

  338.                 plong = pNum->_num;

  339.                 _asm
  340.                 {
  341.                         MOV ESI,plong
  342.                 }
  343.                
  344.                 for(i=0 ; i<pNum->_len ; i++)
  345.                 {
  346.                         _asm
  347.                         {
  348.                                 MOV        EAX,[ESI]
  349.                                 MUL number
  350.                                 ADD EAX,carry
  351.                                 ADC EDX,0
  352.                                 MOV EBX,BASE
  353.                                 DIV EBX
  354.                                 MOV [ESI],EDX
  355.                                 MOV carry,EAX
  356.                                 ADD        ESI,4
  357.                         }
  358.                 }

  359.                 if(carry != 0)
  360.                 {
  361.                         pNum->_num[i++] = carry;
  362.                 }

  363.                 pNum->_len = i;

  364.                 nRet = 1;
  365.         }while(0);

  366.         return nRet;
  367. }

  368. //大整数与一个 int 相除
  369. int DivNumber(LPNUMERIC pNum,int number)
  370. {
  371.         int nRet = 0;
  372.         int carry = pNum->_len;
  373.         int * plong = pNum->_num;

  374.         do
  375.         {
  376.                 if(!IS_INITED(pNum))
  377.                 {
  378.                         break;
  379.                 }
  380.                
  381.                 plong += (pNum->_len - 1);

  382.                 _asm
  383.                 {
  384.                         MOV ECX,carry
  385.                         MOV ESI,plong
  386.                         XOR EDX,EDX
  387.                 _DivLoop:
  388.                         MOV EAX,EDX
  389.                         MOV EBX,BASE
  390.                         MUL EBX
  391.                         ADD EAX,[ESI]
  392.                         ADC EDX,0
  393.                         MOV EBX,number
  394.                         DIV EBX
  395.                         MOV [ESI],EAX
  396.                         SUB ESI,4
  397.                         TEST EAX,EAX
  398.                         JNZ _NotZero
  399.                         DEC carry
  400.                 _NotZero:
  401.                         LOOP _DivLoop
  402.                 }

  403.                 pNum->_len = carry;

  404.                 nRet = 1;
  405.         }while(0);

  406.         return nRet;
  407. }

  408. int main()
  409. {
  410.         int i;
  411.         int n,a;
  412.         NUMERIC sum,num;
  413.         char buffer[4096] = {0};

  414.         InitNumeric(&sum,100);
  415.         InitNumeric(&num,100);

  416.         while(1)
  417.         {
  418.                 scanf("%d%d",&n,&a);
  419.                 if(n == 0)
  420.                 {
  421.                         break;
  422.                 }

  423.                 sprintf(buffer,"%d",a);
  424.                 SetNumeric(&sum,buffer);
  425.                 for(i=1 ; i<n ; i++)
  426.                 {
  427.                         sprintf(buffer,"%s%d",buffer,a);
  428.                         SetNumeric(&num,buffer);
  429.                         AddNumeric(&sum,&num);
  430.                 }
  431.                 Number2String(&sum,buffer);
  432.                 printf("%s\n",buffer);
  433.         }

  434.         UninitNumeric(&num);
  435.         UninitNumeric(&sum);
  436.         return 0;
  437. }
复制代码
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2020-11-8 12:48:44 | 显示全部楼层
  1. #include <stdio.h>

  2. main(void)
  3. {
  4.         int a[500] , n[500] , Sn , b , i , k , m                                             ;
  5.         for(m = 0 ;;) {
  6.                 scanf("%d%d" , & n[m] , & a[m])                                              ;
  7.                 if(n[m]) m ++                                                                ;
  8.                 else break                                                                   ;
  9.         }
  10.         for(k = 0 ; k < m ; k ++) {
  11.                 for(Sn = 0 , b = a[k] , i = 0 ; i < n[k] ; i ++ , b = b * 10 + a[k]) Sn += b ;
  12.                 printf("%d\n" , Sn)                                                          ;
  13.         }
  14. }
复制代码

编译、运行实况:
  1. D:\00.Excise\C>g++ -o x x.c

  2. D:\00.Excise\C>x
  3. 2 4
  4. 3 8
  5. 4 9
  6. 5 2
  7. 8 7
  8. 10 1
  9. 0 0
  10. 48
  11. 984
  12. 11106
  13. 24690
  14. 86419746
  15. 1234567900

  16. D:\00.Excise\C>
复制代码
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-11-8 16:09:01 | 显示全部楼层
本帖最后由 ckh020303 于 2020-11-8 16:11 编辑
jackz007 发表于 2020-11-8 12:48
编译、运行实况:


你好,你这个代码和我的是一个情况的,我去试了下,当n=1000时,sn只能取到差不多2147483647,而答案的sn是1000位数的,我想要了解的是可不可以把一个很大位数的数,每一位数用一个数组来表示,举例如下:
就如2147483647   a[0]表示个位的7
                           a[1]表示十位的4
                           a[2]表示百位的6
                           .....以此类推
最后逆向输出来
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-11-8 16:24:55 | 显示全部楼层
ckh020303 发表于 2020-11-8 16:09
你好,你这个代码和我的是一个情况的,我去试了下,当n=1000时,sn只能取到差不多2147483647,而答案的 ...

        1000 位数的整型数你准备用什么数据类型来保存,用什么手段来做运算?
  1. #include <stdio.h>

  2. int main(void)
  3. {
  4.         long long a[24] , d , k , m , n                        ;
  5.         n = 2147483647                                         ;
  6.         for(d = n  , m = 0 ; d ; d /= 10 , m ++) a[m] = d % 10 ;
  7.         printf("%I64d" , a[m - 1])                             ;
  8.         for(k = m - 1 ; k ; k --) printf(" %I64d" , a[k - 1])  ;
  9.         printf("\n")                                           ;
  10. }
复制代码

        编译、运行实况:
  1. D:\00.Excise\C>g++ -o x x.c

  2. D:\00.Excise\C>x
  3. 2 1 4 7 4 8 3 6 4 7

  4. D:\00.Excise\C>
复制代码

小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-11-9 10:08:37 | 显示全部楼层    本楼为最佳答案   
大整数的加减乘除都有。

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>

  4. /***********************************************************************************
  5. 用整形数组解决大数高精度计算问题
  6. 32位系统下 unsigned int 最大存储的数为:4294967296
  7. 为了防止最高位为1导致负数的问题,数组中每个元素最大只存储 999999999
  8. 为了解决溢出问题,在做乘法和除法的时候用到了内嵌汇编,某些编译器可能不支持
  9. ***********************************************************************************/
  10. #define BASE        (1000000000)
  11. #define        NUM_LEN        (9)
  12. #define IS_INITED(p)        ((p->_num != 0) && (p->_initFlag == 0))

  13. //定义一个结构体来存储大整数
  14. typedef struct tagNumeric
  15. {
  16.         //存储大数的数组
  17.         int * _num;
  18.         //为数组分配的内存大小,以 int 为单位,计算字节数则为:_size * sizeof(int)
  19.         int _size;
  20.         //大数的长度,即数组中的有用长度
  21.         int _len;
  22.         //结构体初始化标记
  23.         //鉴于某些编译器初始化变量,某些编译器不初始化变量
  24.         //因此,认为 _initFlag == 0 && _num != 0 时,结构体被初始化
  25.         int _initFlag;
  26. }NUMERIC,*LPNUMERIC;

  27. //初始化大整数结构体,为数组分配内存
  28. int InitNumeric(LPNUMERIC pNum,int size)
  29. {
  30.         int nRet = 0;
  31.         do
  32.         {
  33.                 if(IS_INITED(pNum))
  34.                 {
  35.                         break;
  36.                 }

  37.                 pNum->_num = (int *)malloc(size * sizeof(int));
  38.                 if(pNum->_num == 0)
  39.                 {
  40.                         break;
  41.                 }

  42.                 memset(pNum->_num,0,size*sizeof(int));

  43.                 pNum->_len = 0;
  44.                 pNum->_initFlag = 0;
  45.                 pNum->_size = size;

  46.                 nRet = 1;
  47.         }while(0);

  48.         return nRet;
  49. }

  50. //当分配的内存不足以存储大整数时,为之重新分配内存
  51. //建议为防止内存频繁地被重新分配,可以在初始化时分配大一点
  52. int ReinitNumeric(LPNUMERIC pNum,int size)
  53. {
  54.         int nRet = 0;
  55.        
  56.         do
  57.         {
  58.                 if(!IS_INITED(pNum))
  59.                 {
  60.                         break;
  61.                 }
  62.                
  63.                 if(size <= pNum->_size)
  64.                 {
  65.                         break;
  66.                 }
  67.                
  68.                 pNum->_num = (int *)realloc(pNum->_num,size*sizeof(int));

  69.                 if(pNum->_num == 0)
  70.                 {
  71.                         break;
  72.                 }

  73.                 memset(pNum->_num + pNum->_size,0,(size - pNum->_size)*sizeof(int));
  74.                 pNum->_size = size;

  75.                 nRet = 1;
  76.         }while(0);
  77.        
  78.         return nRet;
  79. }

  80. //释放内存
  81. void UninitNumeric(LPNUMERIC pNum)
  82. {
  83.         if(IS_INITED(pNum))
  84.         {
  85.                 free(pNum->_num);
  86.                 pNum->_num = 0;
  87.         }
  88. }

  89. //给结构体一个初始整数值,这个值必须小于 1000000000
  90. int SetNumber(LPNUMERIC pNum,int number)
  91. {
  92.         int nRet = 0;
  93.        
  94.         do
  95.         {
  96.                 if(number >= BASE)
  97.                 {
  98.                         break;
  99.                 }

  100.                 if(!IS_INITED(pNum) && InitNumeric(pNum,1)==0)
  101.                 {
  102.                         break;
  103.                 }
  104.                
  105.                 pNum->_num[0] = number;
  106.                 pNum->_len = 1;

  107.                 nRet = 1;
  108.         }while(0);

  109.         return nRet;
  110. }

  111. //当需要给结构体一个大于999999999的初始值时,
  112. //可以用字符串形式给它赋值,实例如下:
  113. /*
  114.         NUMERIC num;
  115.         SetNumeric(&num,"1234567890987654321");
  116. */
  117. int SetNumeric(LPNUMERIC pNum,char * number)
  118. {
  119.         int i = 0;
  120.         int nRet = 0;
  121.         char cByte = 0;
  122.         int value = 0;
  123.         int power = 0;
  124.         int index =0;
  125.         int nLen = strlen(number);
  126.         int size = nLen / NUM_LEN + (nLen % NUM_LEN == 0 ? 0 : 1);
  127.        
  128.        
  129.         do
  130.         {
  131.                 if(nLen == 0)
  132.                 {
  133.                         break;
  134.                 }
  135.                
  136.                 if(!IS_INITED(pNum) && InitNumeric(pNum,size) == 0)
  137.                 {
  138.                         break;
  139.                 }

  140.                 if(size > pNum->_size && ReinitNumeric(pNum,size) == 0)
  141.                 {
  142.                         break;
  143.                 }
  144.                
  145.                 for(i=0 ; i<nLen ; i++)
  146.                 {
  147.                         if(number[i]<'0' || number[i]>'9')
  148.                         {
  149.                                 break;
  150.                         }
  151.                 }
  152.                 if(i < nLen--)
  153.                 {
  154.                         break;
  155.                 }


  156.                 for(i=nLen ; i>=0 ; i--)
  157.                 {
  158.                         if((nLen - i) % NUM_LEN == 0)
  159.                         {
  160.                                 if(nLen - i != 0)
  161.                                 {
  162.                                         pNum->_num[index++] = value;
  163.                                 }

  164.                                 value = 0;
  165.                                 power = 1;
  166.                         }
  167.                         cByte = number[i] - 0x30;
  168.                         value += power * cByte;
  169.                         power *= 10;
  170.                 }

  171.                 if(value != 0)
  172.                 {
  173.                         pNum->_num[index++] = value;
  174.                 }

  175.                 pNum->_len = index;               
  176.                 nRet = 1;
  177.         }while(0);

  178.         return nRet;
  179. }

  180. //将大整数转化成字符串,以便于输出。
  181. //当 number 指针传 0 时,函数将返回转化成字符串所需要的内存空间
  182. //实例如下:
  183. /*
  184.         int len =0;
  185.         char * buffer;
  186.         NUMERIC num;
  187.         SetNumeric(&num,"12345678909876543121");
  188.         len = Number2String(&num,0);
  189.         buffer = (char *)malloc(len);
  190.         Number2String(&num,buffer);

  191. */
  192. int Number2String(LPNUMERIC pNum,char * number)
  193. {
  194.         int i = 0;
  195.         int nRet = 0;
  196.         char buffer[16] = {0};
  197.        
  198.         do
  199.         {
  200.                 if(!IS_INITED(pNum))
  201.                 {
  202.                         break;
  203.                 }

  204.                 if(number == 0)
  205.                 {
  206.                         nRet = pNum->_len * NUM_LEN + 1;
  207.                         break;
  208.                 }

  209.                 number[0] = 0;
  210.                
  211.                 for(i=pNum->_len-1 ; i>=0 ; i--)
  212.                 {
  213.                         if(i == pNum->_len-1)
  214.                         {
  215.                                 sprintf(buffer,"%d",pNum->_num[i]);
  216.                         }
  217.                         else
  218.                         {
  219.                                 sprintf(buffer,"%09d",pNum->_num[i]);
  220.                         }
  221.                         strcat(number,buffer);
  222.                 }

  223.                 nRet = strlen(number);
  224.         }while(0);

  225.         return nRet;
  226. }

  227. //大整数与一个 int 相加
  228. int AddNumber(LPNUMERIC pNum,int number)
  229. {
  230.         int i;
  231.         int nRet = 0;
  232.         int carry = 0;
  233.         unsigned int value = 0;
  234.        
  235.         do
  236.         {
  237.                 if(!IS_INITED(pNum))
  238.                 {
  239.                         break;
  240.                 }
  241.                
  242.                 if(pNum->_size == pNum->_len && ReinitNumeric(pNum,pNum->_size + 1) == 0)
  243.                 {
  244.                         break;
  245.                 }
  246.                                
  247.                 for(i=0 ; i<pNum->_len ; i++)
  248.                 {
  249.                         value = pNum->_num[i] + number + carry;
  250.                         pNum->_num[i] = value % BASE;
  251.                         carry = value / BASE;
  252.                 }
  253.                
  254.                 if(carry != 0)
  255.                 {
  256.                         pNum->_num[i++] = carry;
  257.                 }
  258.                 pNum->_len = i;
  259.                
  260.                 nRet = 1;
  261.         }while(0);
  262.        
  263.         return nRet;       
  264. }

  265. //大整数加另外一个大整数
  266. int AddNumeric(LPNUMERIC pNum,LPNUMERIC pAdd)
  267. {
  268.         int i;
  269.         int nRet = 0;
  270.         int carry = 0;
  271.         int size = 0;
  272.         unsigned int value = 0;
  273.        
  274.         do
  275.         {
  276.                 if(!IS_INITED(pNum) || !IS_INITED(pAdd))
  277.                 {
  278.                         break;
  279.                 }
  280.                
  281.                 if(pNum->_size < pAdd->_len)
  282.                 {
  283.                         size = pAdd->_len + 1;
  284.                 }
  285.                 else if(pNum->_size == pNum->_len)
  286.                 {
  287.                         size = pNum->_size + 1;
  288.                 }

  289.                 if(size != 0 && ReinitNumeric(pNum,size) == 0)
  290.                 {
  291.                         break;
  292.                 }
  293.                
  294.                 size = pNum->_len > pAdd->_len ? pNum->_len : pAdd->_len;

  295.                 for(i=0 ; i<size ; i++)
  296.                 {
  297.                         value = carry;

  298.                         if(i < pNum->_len)
  299.                         {
  300.                                 value += pNum->_num[i];
  301.                         }

  302.                         if(i < pAdd->_len)
  303.                         {
  304.                                 value += pAdd->_num[i];
  305.                         }

  306.                         pNum->_num[i] = value % BASE;
  307.                         carry = value / BASE;
  308.                 }
  309.                
  310.                 if(carry != 0)
  311.                 {
  312.                         pNum->_num[i++] = carry;
  313.                 }
  314.                 pNum->_len = i;
  315.                
  316.                 nRet = 1;
  317.         }while(0);
  318.        
  319.         return nRet;       
  320. }

  321. //大整数与一个 int 相乘
  322. int MulNumber(LPNUMERIC pNum,int number)
  323. {
  324.         int i;
  325.         int nRet = 0;
  326.         int carry = 0;
  327.         int * plong = 0;

  328.         do
  329.         {
  330.                 if(!IS_INITED(pNum))
  331.                 {
  332.                         break;
  333.                 }

  334.                 if(pNum->_size == pNum->_len && ReinitNumeric(pNum,pNum->_size + 1) == 0)
  335.                 {
  336.                         break;
  337.                 }

  338.                 plong = pNum->_num;

  339.                 _asm
  340.                 {
  341.                         MOV ESI,plong
  342.                 }
  343.                
  344.                 for(i=0 ; i<pNum->_len ; i++)
  345.                 {
  346.                         _asm
  347.                         {
  348.                                 MOV        EAX,[ESI]
  349.                                 MUL number
  350.                                 ADD EAX,carry
  351.                                 ADC EDX,0
  352.                                 MOV EBX,BASE
  353.                                 DIV EBX
  354.                                 MOV [ESI],EDX
  355.                                 MOV carry,EAX
  356.                                 ADD        ESI,4
  357.                         }
  358.                 }

  359.                 if(carry != 0)
  360.                 {
  361.                         pNum->_num[i++] = carry;
  362.                 }

  363.                 pNum->_len = i;

  364.                 nRet = 1;
  365.         }while(0);

  366.         return nRet;
  367. }

  368. //大整数与一个 int 相除
  369. int DivNumber(LPNUMERIC pNum,int number)
  370. {
  371.         int nRet = 0;
  372.         int carry = pNum->_len;
  373.         int * plong = pNum->_num;

  374.         do
  375.         {
  376.                 if(!IS_INITED(pNum))
  377.                 {
  378.                         break;
  379.                 }
  380.                
  381.                 plong += (pNum->_len - 1);

  382.                 _asm
  383.                 {
  384.                         MOV ECX,carry
  385.                         MOV ESI,plong
  386.                         XOR EDX,EDX
  387.                 _DivLoop:
  388.                         MOV EAX,EDX
  389.                         MOV EBX,BASE
  390.                         MUL EBX
  391.                         ADD EAX,[ESI]
  392.                         ADC EDX,0
  393.                         MOV EBX,number
  394.                         DIV EBX
  395.                         MOV [ESI],EAX
  396.                         SUB ESI,4
  397.                         TEST EAX,EAX
  398.                         JNZ _NotZero
  399.                         DEC carry
  400.                 _NotZero:
  401.                         LOOP _DivLoop
  402.                 }

  403.                 pNum->_len = carry;

  404.                 nRet = 1;
  405.         }while(0);

  406.         return nRet;
  407. }

  408. int main()
  409. {
  410.         int i;
  411.         int n,a;
  412.         NUMERIC sum,num;
  413.         char buffer[4096] = {0};

  414.         InitNumeric(&sum,100);
  415.         InitNumeric(&num,100);

  416.         while(1)
  417.         {
  418.                 scanf("%d%d",&n,&a);
  419.                 if(n == 0)
  420.                 {
  421.                         break;
  422.                 }

  423.                 sprintf(buffer,"%d",a);
  424.                 SetNumeric(&sum,buffer);
  425.                 for(i=1 ; i<n ; i++)
  426.                 {
  427.                         sprintf(buffer,"%s%d",buffer,a);
  428.                         SetNumeric(&num,buffer);
  429.                         AddNumeric(&sum,&num);
  430.                 }
  431.                 Number2String(&sum,buffer);
  432.                 printf("%s\n",buffer);
  433.         }

  434.         UninitNumeric(&num);
  435.         UninitNumeric(&sum);
  436.         return 0;
  437. }
复制代码
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-11-9 10:10:06 | 显示全部楼层
运行结果
未命名.JPG

小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-11-9 10:20:54 | 显示全部楼层

兄弟太猛了
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2025-5-9 20:18

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表