Pascal高精压4位之操作符重载实现

高精重要性没的说,最近爱上了用操作符重载来写高精,干脆把高精都整理出来一个程序里面。下面这个程序包括了:
  1. 字符串转高精数组
  2. 高精+高精
  3. 高精+低精
  4. 高精-高精(答案必须为非负数)
  5. 高精*高精
  6. 高精*低精
  7. 高精div低精
  8. 高精数之间的<=、>=、<、>、=判断
  9. 高精数的输出
  10. 以上全都是压4位
  11. 一个小小的demo
可以发现操作符重载之后运算符的优先级和结合性不变。 参数表中的const很重要,否则复制数组会浪费很多时间。另外能压四位的高精不得不注意一下字符串读入,有时候长度是超过255的,注意改成ansistring。 程序如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
const MAXLEN=100;
type bigint=array[0..MAXLEN] of longint;
var a,b,c,d:bigint;
operator :=(const str:string) a:bigint;
  var k:longint;
  begin
    fillchar(a,sizeof(a),0);
    k:=length(str)-3;
    repeat
      inc(a[0]);
      if k<=0 then val(copy(str,1,3+k),a[a[0]])
      else val(copy(str,k,4),a[a[0]]);
      dec(k,4);
    until (k<=-3);
  end;
operator +(const a,b:bigint) c:bigint;
  var i,x,larger:longint;
  begin
    x:=0;
    if a[0]>b[0] then larger:=a[0] else larger:=b[0];
    for i:=1 to larger do begin
      x:=a[i]+b[i]+x div 10000;
      c[i]:=x mod 10000;
    end;
    if x>=10000 then begin
      c[0]:=larger+1;
      c[c[0]]:=1;
    end else c[0]:=larger;
  end;
operator +(const a:bigint;const b:longint) c:bigint;
  var i,x:longint;
  begin
    c:=a;
    x:=b+a[1];
    for i:=1 to a[0] do begin
      c[i]:=x mod 10000;
      x:=x div 10000+a[i+1];
      if x=0 then break;
    end;
    if x<>0 then begin
      inc(c[0]);
      c[c[0]]:=1;
    end;
  end;
operator -(const a,b:bigint) c:bigint;
  var i,x:longint;
  begin
    fillchar(c,sizeof(c),0);
    x:=0;
    for i:=1 to a[0] do begin
      x:=c[i]+a[i]-b[i]+x div 10000;
      if x<0 then begin
        inc(x,10000);
        dec(c[i+1]);
      end;
      c[i]:=x;
    end;
    c[0]:=a[0];
    while (c[0]>0)and(c[c[0]]=0) do dec(c[0]);
  end;
operator *(const a,b:bigint) c:bigint;
  var i,j,x:longint;
  begin
    fillchar(c,sizeof(c),0);
    for i:=1 to a[0] do begin
      x:=0;
      for j:=1 to b[0] do begin
        x:=x+a[i]*b[j]+c[i+j-1];
        c[i+j-1]:=x mod 10000;
        x:=x div 10000;
      end;
      c[i+j]:=x;
    end;
    c[0]:=a[0]+b[0];
    while (c[0]>0)and(c[c[0]]=0) do dec(c[0]);
  end;
operator *(const a:bigint;const b:longint) c:bigint;
  var i,x:longint;
  begin
    fillchar(c,sizeof(c),0);
    x:=0;
    for i:=1 to a[0] do begin
      x:=x+a[i]*b;
      c[i]:=x mod 10000;
      x:=x div 10000;
    end;
    c[0]:=a[0];
    while x>0 do begin
      inc(c[0]);
      c[c[0]]:=x mod 10000;
      x:=x div 10000;
    end;
  end;
operator div(const a:bigint;const b:longint) c:bigint;
  var i,x:longint;
  begin
    fillchar(c,sizeof(c),0);
    x:=0;
    for i:=a[0] downto 1 do begin
      c[i]:=(x*10000+a[i]) div b;
      x:=(x*10000+a[i]) mod b;
    end;
    c[0]:=a[0];
    while (c[0]>0)and(c[c[0]]=0) do dec(c[0]);
  end;
operator =(const a,b:bigint) c:boolean;
  var i:longint;
  begin
    if a[0]<>b[0] then exit(false);
    for i:=1 to a[0] do if a[i]<>b[i] then exit(false);
    exit(true);
  end;
operator >(const a,b:bigint) c:boolean;
  var i:longint;
  begin
    if a[0]<>b[0] then exit(a[0]>b[0]);
    for i:=a[0] downto 1 do if a[i]<>b[i] then exit(a[i]>b[i]);
    exit(false);
  end;
operator >=(const a,b:bigint) c:boolean;
  var i:longint;
  begin
    if a[0]<>b[0] then exit(a[0]>=b[0]);
    for i:=a[0] downto 1 do if a[i]<>b[i] then exit(a[i]>=b[i]);
    exit(false);
  end;
operator <(const a,b:bigint) c:boolean;
  var i:longint;
  begin
    if a[0]<>b[0] then exit(a[0]<b[0]);
    for i:=a[0] downto 1 do if a[i]<>b[i] then exit(a[i]<b[i]);
    exit(false);
  end;
operator <=(const a,b:bigint) c:boolean;
  var i:longint;
  begin
    if a[0]<>b[0] then exit(a[0]<b[0]);
    for i:=a[0] downto 1 do if a[i]<>b[i] then exit(a[i]<=b[i]);
    exit(false);
  end;
procedure print(const a:bigint);
  var i:longint;
  begin
    write(a[a[0]]);
    for i:=a[0]-1 downto 1 do begin
      if a[i]<10 then write('000') else
      if a[i]<100 then write('00') else
      if a[i]<1000 then write('0');
      write(a[i]);
    end;
    writeln;
  end;
begin
  a:='1234567890';
  b:='12345678901';
  c:='123456789012';
  d:='1234567890123';
  print(b+a);
  print(c-b);
  print(d*c);
  print(d div 100);
  print(a*768);
  print(b+22);
  writeln((a+b)*c < (d-c)*a);
  writeln(a >= b);
  writeln(c*100 = d);
  writeln(a*c <= b*c);
  writeln(a+d > b+c);
  a:='2';
  b:='3';
  c:='4';
  print(a+b*c);
  print((a+b)*c);
  readln;
end.

Comments