MathgeomGLS
311 строк · 7.6 Кб
1{**********************************************************************}
2{ }
3{ "The contents of this file are subject to the Mozilla Public }
4{ License Version 1.1 (the "License"); you may not use this }
5{ file except in compliance with the License. You may obtain }
6{ a copy of the License at http://www.mozilla.org/MPL/ }
7{ }
8{ Software distributed under the License is distributed on an }
9{ "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express }
10{ or implied. See the License for the specific language }
11{ governing rights and limitations under the License. }
12{ }
13{ Copyright Creative IT. }
14{ Current maintainer: Eric Grange }
15{ }
16{**********************************************************************}
17unit dwsBigInteger;
18
19{$I dws.inc}
20
21interface
22
23uses
24Classes, System.SysUtils, dwsUtils, gmp_lib; // gmp_obj
25
26type
27
28TBigInteger = class;
29
30IBigInteger = interface
31['{C78B75B3-DF67-4E60-8B38-AD8719F175D4}']
32function Obj : TBigInteger;
33function Clone : TBigInteger;
34end;
35
36TBigInteger = class (TInterfacedObject, IBigInteger)
37private
38mpz : mpz_t;
39
40function Obj : TBigInteger;
41
42public
43constructor Create;
44destructor Destroy; override;
45
46function Clone : TBigInteger;
47end;
48
49BigInteger = record
50private
51FData : IBigInteger;
52
53procedure Allocate; inline;
54
55public
56procedure Assign(const v : Integer); overload; inline;
57procedure Assign(const v : Int64); overload; inline;
58
59function ToHexString : String;
60procedure FromHexString(const s : String);
61
62function ToFloat : Double;
63(*
64class operator Explicit(const v : Int64) : BigInteger; inline;
65*)
66class operator Add(const a, b : BigInteger) : BigInteger;
67(* class operator Add(const a : BigInteger; const b : Int64) : BigInteger;
68class operator Add(const a : Int64; const b : BigInteger) : BigInteger;
69class operator Subtract(const a, b : BigInteger) : BigInteger;
70class operator Subtract(const a : BigInteger; const b : Int64) : BigInteger;
71class operator Subtract(const a : Int64; const b : BigInteger) : BigInteger;
72
73class operator BitwiseAnd(const a, b : BigInteger) : BigInteger;
74class operator BitwiseOr(const a, b : BigInteger) : BigInteger;
75class operator BitwiseXor(const a, b : BigInteger) : BigInteger;
76*)
77class operator Equal(const a, b : BigInteger) : Boolean;
78class operator NotEqual(const a, b : BigInteger) : Boolean; inline;
79end;
80
81EBigIntegerException = class (Exception);
82
83// ------------------------------------------------------------------
84// ------------------------------------------------------------------
85// ------------------------------------------------------------------
86implementation
87// ------------------------------------------------------------------
88// ------------------------------------------------------------------
89// ------------------------------------------------------------------
90
91// ------------------
92// ------------------ TBigInteger ------------------
93// ------------------
94
95// Create
96//
97constructor TBigInteger.Create;
98begin
99mpz_init(mpz);
100end;
101
102// Destroy
103//
104destructor TBigInteger.Destroy;
105begin
106inherited;
107mpz_clear(mpz);
108end;
109
110// Obj
111//
112function TBigInteger.Obj : TBigInteger;
113begin
114Result := Self;
115end;
116
117// Clone
118//
119function TBigInteger.Clone : TBigInteger;
120begin
121Result := TBigInteger.Create;
122mpz_set(Result.mpz, mpz);
123end;
124
125// ------------------
126// ------------------ BigInteger ------------------
127// ------------------
128
129// Allocate
130//
131procedure BigInteger.Allocate;
132begin
133if FData=nil then FData := TBigInteger.Create;
134end;
135
136// Assign
137//
138procedure BigInteger.Assign(const v : Int32);
139begin
140Allocate;
141mpz_set_si(FData.Obj.mpz, v);
142end;
143
144// Assign
145//
146procedure BigInteger.Assign(const v : Int64);
147begin
148Allocate;
149mpz_set_int64(FData.Obj.mpz, v);
150end;
151
152// ToHexString
153//
154function BigInteger.ToHexString : String;
155var
156n : Integer;
157obj : TBigInteger;
158buf : RawByteString;
159begin
160if FData = nil then Exit('0');
161obj := FData.Obj;
162n := mpz_sizeinbase(obj.mpz, 16) + 1;
163SetLength(buf, n);
164mpz_get_str(PAnsiChar(buf), 16, obj.mpz);
165RawByteStringToScriptString(buf, Result);
166end;
167
168// FromHexString
169//
170procedure BigInteger.FromHexString(const s : String);
171var
172i, len, err : Integer;
173nb32 : Integer;
174buf : RawByteString;
175begin
176if s = '0' then begin
177FData := nil;
178Exit;
179end;
180ScriptStringToRawByteString(s, buf);
181Allocate;
182err := mpz_set_str(FData.Obj.mpz, PAnsiChar(s), 16);
183if err <> 0 then
184raise EBigIntegerException.CreateFmt('Conversion error from hexadecimal (%d)', [err]);
185end;
186
187// ToFloat
188//
189function BigInteger.ToFloat : Double;
190begin
191if FData = nil then Exit(0);
192Result := mpz_get_d(FData.Obj.mpz);
193end;
194
195(*
196// Explicit
197//
198class operator BigInteger.Explicit(const v : Int64) : BigInteger;
199begin
200Result.Assign(v);
201end;
202*)
203// Add
204//
205class operator BigInteger.Add(const a, b : BigInteger) : BigInteger;
206begin
207if a.FData = nil then begin
208if b.FData = nil then
209Result.FData := nil
210else Result.FData := b.FData.Clone
211end else if b.FData = nil then
212Result.FData := a.FData.Clone
213else begin
214Result.Allocate;
215mpz_add(Result.FData.Obj.mpz, a.FData.Obj.mpz, b.FData.Obj.mpz);
216end;
217end;
218(*
219// Add
220//
221class operator BigInteger.Add(const a : BigInteger; const b : Int64) : BigInteger;
222begin
223Result := a + BigInteger(b);
224end;
225
226// Add
227//
228class operator BigInteger.Add(const a : Int64; const b : BigInteger) : BigInteger;
229begin
230Result := BigInteger(a) + b;
231end;
232
233// Subtract
234//
235class operator BigInteger.Subtract(const a, b : BigInteger) : BigInteger;
236begin
237Result.High := a.High - b.High;
238Result.Low := a.Low - b.Low;
239if Result.Low > a.Low then
240Dec(Result.High);
241end;
242
243// Subtract
244//
245class operator BigInteger.Subtract(const a : BigInteger; const b : Int64) : BigInteger;
246begin
247Result := a - BigInteger(b);
248end;
249
250// Subtract
251//
252class operator BigInteger.Subtract(const a : Int64; const b : BigInteger) : BigInteger;
253begin
254Result := BigInteger(a) - b;
255end;
256
257// BitwiseAnd
258//
259class operator BigInteger.BitwiseAnd(const a, b : BigInteger) : BigInteger;
260begin
261Result.High := a.High and b.High;
262Result.Low := a.Low and b.Low;
263end;
264
265// BitwiseOr
266//
267class operator BigInteger.BitwiseOr(const a, b : BigInteger) : BigInteger;
268begin
269Result.High := a.High or b.High;
270Result.Low := a.Low or b.Low;
271end;
272
273// BitwiseXor
274//
275class operator BigInteger.BitwiseXor(const a, b : BigInteger) : BigInteger;
276begin
277Result.High := a.High xor b.High;
278Result.Low := a.Low xor b.Low;
279end;
280*)
281// Equal
282//
283class operator BigInteger.Equal(const a, b : BigInteger) : Boolean;
284var
285i, na : Integer;
286begin
287mpz_cm
288Result:=(a.FHigh32=b.FHigh32);
289if Result then begin
290a.Pack;
291b.Pack;
292na:=Length(a.FData);
293if na = Length(b.FData) then begin
294for i := 0 to na-1 do begin
295if a.FData[i] <> b.FData[i] then begin
296Result := False;
297Break;
298end;
299end;
300end else Result := False;
301end;
302end;
303
304// NotEqual
305//
306class operator BigInteger.NotEqual(const a, b : BigInteger) : Boolean;
307begin
308Result := not (a = b);
309end;
310
311end.
312