• 玩具程序:bigInt


    #0 为什么称作玩具程序?
    1、实现简单,也就是效率一般。
    2、只具备无符号数的加、乘运算功能。
     
    #1 如何实现
    以1792为例,用数组0号元素存储2,1号元素存储9,依此类推...
    下面是大整数的存储结构图。

    存储结构定义:

    1 #define MAXDIGITS 64
    2 
    3 typedef struct {
    4     int lastdigit;
    5     char digits[MAXDIGITS];
    6 } bigNum;

    加法实现:按位相加,再加上进位carry。两个数长度未必相同,所以高位的处理需要特别对待。
    乘法实现:乘法其实是用加法来实现的,下面列出了伪码实现。

     1 int multiplyBigNum(bigNum * src, bigNum * dst){
     2     bigNum result;
     3     bigNum t;
     4 
     5     for each digit x in dst{
     6         some bookkeeping;
     7         multiplyDigit(src, x, &t);
     8         addBigNum(&result, &t);
     9     }
    10 
    11     copyBigNum(&result, src);
    12 
    13     return 0;
    14 }

    #2 除了初始化bigInt外没有 除法、求余 运算:我构造了查找表,但这也使得程序代码变得更长了。
    查找表的构造过程:写几行输出代码,控制台输入输出重定向,拷贝粘帖。如果是手工的话,很可能会出错。

     1     unsigned char cacheMgr[96][2]={
     2         00,    01,    02,    03,    04,   
     3         05,    06,    07,    08,    09,   
     4         10,    11,    12,    13,    14,   
     5         15,    16,    17,    18,    19,   
     6         20,    21,    22,    23,    24,   
     7         25,    26,    27,    28,    29,   
     8         30,    31,    32,    33,    34,   
     9         35,    36,    37,    38,    39,   
    10         40,    41,    42,    43,    44,   
    11         45,    46,    47,    48,    49,   
    12         50,    51,    52,    53,    54,   
    13         55,    56,    57,    58,    59,   
    14         60,    61,    62,    63,    64,   
    15         65,    66,    67,    68,    69,   
    16         70,    71,    72,    73,    74,   
    17         75,    76,    77,    78,    79,   
    18         80,    81,    82,    83,    84,   
    19         85,    86,    87,    88,    89,   
    20         90,    91,    92,    93,    94,   
    21         95
    22     };

    #3 阶乘运算31!,改下参数运算256!也行的, 运行时间也会长些

     1 int main(){
     2     bigNum src;
     3     bigNum dst;
     4     
     5     makeBigNum(1, &src);
     6     
     7     for (int i=1; i<32; i++){
     8         makeBigNum(i, &dst);
     9         multiplyBigNum(&src, &dst);
    10         printfBigNum(&src);
    11     }
    12 
    13     getchar();
    14     return 0;
    15 }

    #4 更多参考

    显然,高精度数值运算程序库的编写可以称得上相当professional的工作!如果你想动手,最好找些帮手。【1】有递归实现。【2】有四则运算的完整实现。【3】有齐全的综述。【4】没看过,但显然里面会有权威的描述,必然会有的,哈哈。
    【1】Eric S. Roberts. Programming Abstractions in C: A Second Course in Computer Science. Addison-Wesley Educational Publishers Inc.
    【2】Steven S. Skiena Miguel A. Revilla. Programming Challenges. Springer Verlag. Ch5.2 High-Precision Integers.
    【3】Steven S. Skiena. The Algorithm Design Manual, Second Edition. Springer-Verlag. Ch13.9 Arbitrary-Precision Arithmetic.
    【4】D. Knuth. The Art of Computer Programming, Volume 2: Seminumerical Algorithms. Addison-Wesley, Reading MA, third edition, 1997.

    #5 代码参考,拍砖请轻点下手

      1 #include <stdio.h>
      2 #include "bigInt.h"
      3 #define MAXDIGITS 64
      4 
      5 typedef struct {
      6     int lastdigit;
      7     char digits[MAXDIGITS];
      8 } bigNum;
      9 
     10 int makeBigNum(int src, bigNum * bn){
     11     bn->lastdigit = -1;
     12     while (src != 0){
     13         bn->lastdigit ++;
     14         bn->digits[bn->lastdigit] = src % 10;
     15         src = src / 10;
     16     }
     17 
     18     return 0;
     19 }
     20 
     21 int printfBigNum(bigNum * bn){
     22     for(int i=bn->lastdigit; i>=0; i--){
     23         printf("%u", bn->digits[i]);
     24         if (i%3 == 0) printf(" ");
     25     }
     26 
     27     printf("\n");
     28 
     29     return 0;
     30 }
     31 
     32 int addBigNum(bigNum * src, bigNum * dst){
     33     unsigned char cacheMgr[20][2]={
     34         00,    01,    02,    03,    04,   
     35         05,    06,    07,    08,    09,   
     36          10,    11,    12,    13,    14,   
     37          15,    16,    17,    18,    19
     38     };
     39     
     40     bigNum * longNum = src;
     41     int shortLength = dst->lastdigit;
     42     if(dst->lastdigit > src->lastdigit){
     43         longNum = dst;
     44         shortLength = src->lastdigit;
     45     }
     46     int length = longNum->lastdigit;
     47 
     48     int carry = 0;
     49     for (int i=0; i<=shortLength; i++){
     50         unsigned char t = src->digits[i] + dst->digits[i] + carry;
     51         src->digits[i] = cacheMgr[t][1];
     52         carry = cacheMgr[t][0];
     53     }
     54 
     55     for (int i=shortLength+1; i<=length; i++){
     56         unsigned char t = longNum->digits[i] + carry;
     57         src->digits[i] = cacheMgr[t][1];
     58         carry = cacheMgr[t][0];
     59     }
     60 
     61     if (carry == 1){
     62         src->lastdigit = longNum->lastdigit+1;
     63         src->digits[src->lastdigit] = 1;
     64     }
     65     else src->lastdigit = longNum->lastdigit;
     66 
     67     return 0;
     68 }
     69 
     70 // src =====> dst
     71 int copyBigNum(bigNum * src, bigNum * dst){
     72     int length = src->lastdigit;
     73     
     74     dst->lastdigit = length;
     75 
     76     for(int i=0; i<=length; i++)
     77         dst->digits[i] = src->digits[i];
     78 
     79     return 0;
     80 }
     81 
     82 int multiplyDigit(bigNum * src, unsigned char digit, bigNum * t){
     83     unsigned char cacheMgr[96][2]={
     84         00,    01,    02,    03,    04,   
     85         05,    06,    07,    08,    09,   
     86         10,    11,    12,    13,    14,   
     87         15,    16,    17,    18,    19,   
     88         20,    21,    22,    23,    24,   
     89         25,    26,    27,    28,    29,   
     90         30,    31,    32,    33,    34,   
     91         35,    36,    37,    38,    39,   
     92         40,    41,    42,    43,    44,   
     93         45,    46,    47,    48,    49,   
     94         50,    51,    52,    53,    54,   
     95         55,    56,    57,    58,    59,   
     96         60,    61,    62,    63,    64,   
     97         65,    66,    67,    68,    69,   
     98         70,    71,    72,    73,    74,   
     99         75,    76,    77,    78,    79,   
    100         80,    81,    82,    83,    84,   
    101         85,    86,    87,    88,    89,   
    102         90,    91,    92,    93,    94,   
    103         95
    104     };
    105 
    106     int carry = 0;
    107     int length = src->lastdigit;
    108     int x;
    109 
    110     for(int i=0; i<=length; i++){
    111         x = src->digits[i] * digit + carry;
    112         t->lastdigit++;
    113         t->digits[t->lastdigit] = cacheMgr[x][1];
    114         carry = cacheMgr[x][0];
    115     }
    116 
    117     if (carry > 0){
    118         t->lastdigit = t->lastdigit+1;
    119         t->digits[t->lastdigit] = carry;
    120     }
    121 
    122     return 0;
    123 }
    124 
    125 int multiplyBigNum(bigNum * src, bigNum * dst){
    126     bigNum result;
    127     bigNum t;
    128 
    129     makeBigNum(0, &result);
    130 
    131     int length = dst->lastdigit;
    132     for (int i=0; i<=length; i++){
    133         t.lastdigit = i-1;
    134         for (int s=1; s<=i; s++)
    135             t.digits[s-1] = 0;
    136         multiplyDigit(src, dst->digits[i], &t);
    137         addBigNum(&result, &t);
    138     }
    139 
    140     copyBigNum(&result, src);
    141 
    142     return 0;
    143 }
    144 
    145 int main(){
    146     bigNum src;
    147     bigNum dst;
    148     
    149     makeBigNum(1, &src);
    150     
    151     for (int i=1; i<32; i++){
    152         makeBigNum(i, &dst);
    153         multiplyBigNum(&src, &dst);
    154         printfBigNum(&src);
    155     }
    156 
    157     getchar();
    158     return 0;
    159 }
  • 相关阅读:
    UOJ168. 【UR #11】元旦老人与丛林
    luogu3308,LOJ 2196 [SDOI2014]LIS
    CF1349F2. Slime and Sequences (Hard Version)
    6210. wsm
    欧拉数学习小记
    CF1508F. Optimal Encoding
    CF1508C. Complete the MST
    联合省选2021 游记
    一. Docker介绍
    Elasticsearch
  • 原文地址:https://www.cnblogs.com/servo/p/2715867.html
Copyright © 2020-2023  润新知