大整数又称为高精度整数,其含义就是用基本数据类型无法储存其精度的整数。

 

一、大整数的存储

  很简单,使用数组即可。例如定义 int 型数组 d[1000],那么这个数组的每一位代表了存放整数的每一位。整数的高位储存在数组的高位,整数的低位储存在数组的低位

  而为了方便随时获取大整数的长度,一般都会定义一个 int 型变量 len 来记录其长度,结构体如下:

1 // 大整数 
2 struct bign {
3     int d[1000];
4     int len;
5 }; 

  在定义结构体变量后,需要马上初始化结构体,加上“构造函数”,代码如下:

// 大整数 
struct bign {
    int d[1000];
    int len;
    bign() {    // 构造函数 
        memset(d, 0, sizeof(d));
        len = 0;
    } 
}; 

 

 

  而输入大整数时,一般都是先用字符串读入,然后再把字符串另存为至 bign 结构体。由于使用 char 数组进行读入时,整数的高位会变成数组的低位,因此需要让字符串倒着赋给 d[] 数组:

 1 // 将字符串另存至 bign 结构体
 2 bign change(char str[]) {
 3     bign a;
 4     a.len = strlen(str);        // bign 的长度就是数组的长度 
 5     int i;
 6     for(i=0; i<a.len; ++i) {    // 倒着赋值 
 7         a.d[i] = str[a.len-1-i] - '0';
 8     }
 9     return a;
10 }

 

 

  如果要比较两个 bign 变量的大小,规则也很简单:先判断两者的 len 的大小,如果不相等,则以长的为大;如果相等,则从高位到低位进行比较,直到出现某一位不等,就可以判断两个数的大小。代码如下:

 1 // 比较两个大整数变量的大小
 2 // a 大、相等、小分别返回 1、0、-1 
 3 int compare(bign a, bign b) {
 4     if(a.len ? b.len)    return 1;        // a>b
 5     else if(a.len < b.len)    return -1;    // a<b
 6     else {
 7         int i;
 8         for(i=0; i<a.len; ++i) {                // 从高位到低位比较 
 9             if(a.d[i] > b.d[i])    return 1;        // a>b
10             else if(a.d[i] < b.d[i]) return -1;    // a<b
11         }
12         return 0;        // 两者相等 
13     }
14 } 

 

 

 

二、大整数的四则运算

  1. 高精度加法

  容易得到对其中一位进行加法的步骤:将该位上的两个数字与进位相加,得到的结果取个位数作为该位结果,取十位数作为新的进位。代码如下:

 1 // 高精度加法
 2 bign add(bign a, bign b) {
 3     bign c;
 4     int carry = 0;    // 进位
 5     int i;
 6     for(i=0; i<a.len || i<b.len; ++i) {            // 以较长的为界限 
 7         int temp = a.d[i] + b.d[i] + carry;        // 其中一位相加
 8         c.d[c.len++] = temp%10;                    // 取个位
 9         carry = temp/10;                        // 新的进位 
10     } 
11     if(carry != 0) {                // 有进位 
12         c.d[c.len++] = carry;
13     }
14     return c; 
15 } 

  测试一下加法代码,以下为 C 代码:

 1 /*
 2     大整数运算 
 3 */
 4 
 5 #include <stdio.h>
 6 #include <string.h>
 7 #include <math.h>
 8 #include <stdlib.h>
 9 #include <time.h>
10 #include <stdbool.h>
11 
12 // 大整数 
13 typedef struct{
14     int d[1000];
15     int len;
16     // C 中 struct 不能有函数 
17     /*bign() {    // 构造函数 
18         memset(d, 0, sizeof(d));
19         len = 0;
20     }*/ 
21 } bign; 
22 
23 // 大整数初始化 
24 bign init() {
25     bign temp = { {0},0 };
26     return temp;
27 }
28 
29 // 将字符串另存至 bign 结构体
30 bign change(char str[]) {
31     bign a = init();
32     a.len = strlen(str);        // bign 的长度就是数组的长度 
33     int i;
34     for(i=0; i<a.len; ++i) {    // 倒着赋值 
35         a.d[i] = str[a.len-1-i] - '0';
36     }
37     return a;
38 } 
39 
40 // 比较两个大整数变量的大小
41 // a 大、相等、小分别返回 1、0、-1 
42 int compare(bign a, bign b) {
43     if(a.len > b.len)    return 1;        // a>b
44     else if(a.len < b.len)    return -1;    // a<b
45     else {
46         int i;
47         for(i=0; i<a.len; ++i) {                // 从高位到低位比较 
48             if(a.d[i] > b.d[i])    return 1;        // a>b
49             else if(a.d[i] < b.d[i]) return -1;    // a<b
50         }
51         return 0;        // 两者相等 
52     }
53 } 
54 
55 // 高精度加法
56 bign add(bign a, bign b) {
57     bign c = init();
58     int carry = 0;    // 进位
59     int i;
60     for(i=0; i<a.len || i<b.len; ++i) {            // 以较长的为界限 
61         int temp = a.d[i] + b.d[i] + carry;        // 其中一位相加
62         c.d[c.len++] = temp%10;                    // 取个位
63         carry = temp/10;                        // 新的进位 
64     } 
65     if(carry != 0) {                // 有进位 
66         c.d[c.len++] = carry;
67     }
68     return c; 
69 } 
70 
71 // 输出大整数 
72 void print(bign a) {
73     int i;
74     for(i=a.len-1; i>=0; --i) {
75         printf("%d", a.d[i]);
76     }
77     printf("\n");
78 }
79 
80 int main() {
81     char str1[1000], str2[1000];
82     scanf("%s%s", str1, str2);
83     bign a = change(str1);
84     bign b = change(str2);
85     print(add(a, b));
86 
87     return 0;
88 }
测试加法

相关文章: