1 | unit BigInt;
|
---|
2 |
|
---|
3 | interface
|
---|
4 |
|
---|
5 | uses
|
---|
6 | Classes, SysUtils, Math;
|
---|
7 |
|
---|
8 | type
|
---|
9 | TArrayOfByte = array of Byte;
|
---|
10 |
|
---|
11 | TBigIntSize = Byte;
|
---|
12 |
|
---|
13 | { TBigInt }
|
---|
14 |
|
---|
15 | TBigInt = record
|
---|
16 | private
|
---|
17 | FData: array of Byte;
|
---|
18 | function GetData(Index: TBigIntSize): Byte;
|
---|
19 | function GetSize: TBigIntSize;
|
---|
20 | procedure SetData(Index: TBigIntSize; AValue: Byte);
|
---|
21 | procedure SetSize(AValue: TBigIntSize);
|
---|
22 | public
|
---|
23 | class operator Implicit(A: Byte): TBigInt;
|
---|
24 | class operator Implicit(A: Word): TBigInt;
|
---|
25 | class operator Implicit(A: ShortInt): TBigInt;
|
---|
26 | class operator Implicit(A: Integer): TBigInt;
|
---|
27 | class operator Implicit(A: QWord): TBigInt;
|
---|
28 | class operator Implicit(A: Int64): TBigInt;
|
---|
29 | class operator Implicit(A: TBigInt): UInt8; // Byte
|
---|
30 | class operator Implicit(A: TBigInt): Int8; // ShortInt
|
---|
31 | class operator Implicit(A: TBigInt): UInt16; // Word
|
---|
32 | class operator Implicit(A: TBigInt): Int16; // SmallInt
|
---|
33 | class operator Implicit(A: TBigInt): UInt32; // LongWord, DWord, Cardinal
|
---|
34 | class operator Implicit(A: TBigInt): Int32; // Int32, LongInt
|
---|
35 | class operator Implicit(A: TBigInt): UInt64; // QWord
|
---|
36 | class operator Implicit(A: TBigInt): Int64;
|
---|
37 | class operator Implicit(A: TBigInt): PByte;
|
---|
38 | class operator Negative(A: TBigInt): TBigInt;
|
---|
39 | class operator Inc(A: TBigInt) : TBigInt;
|
---|
40 | class operator Dec(A: TBigInt) : TBigInt;
|
---|
41 | class operator Add(A, B: TBigInt): TBigInt;
|
---|
42 | class operator Subtract(A, B: TBigInt): TBigInt;
|
---|
43 | class operator Equal(A, B: TBigInt): Boolean;
|
---|
44 | class operator NotEqual(A, B: TBigInt): Boolean;
|
---|
45 | class operator LessThan(A, B: TBigInt): Boolean;
|
---|
46 | class operator LessThanOrEqual(A, B: TBigInt): Boolean;
|
---|
47 | class operator GreaterThan(A, B: TBigInt): Boolean;
|
---|
48 | class operator GreaterThanOrEqual(A, B: TBigInt): Boolean;
|
---|
49 | class operator BitwiseXor(A, B: TBigInt): TBigInt;
|
---|
50 | class operator BitwiseAnd(A, B: TBigInt): TBigInt;
|
---|
51 | class operator BitwiseOr(A, B: TBigInt): TBigInt;
|
---|
52 | class operator LeftShift(A: TBigInt; B: Integer): TBigInt;
|
---|
53 | class operator RightShift(A: TBigInt; B: Integer): TBigInt;
|
---|
54 | class operator Modulus(A, B: TBigInt): TBigInt;
|
---|
55 | class operator IntDivide(A, B: TBigInt): TBigInt;
|
---|
56 | procedure Shrink;
|
---|
57 | function IsNegative: Boolean;
|
---|
58 | function IsZero: Boolean;
|
---|
59 | function IsPositive: Boolean;
|
---|
60 | procedure Invert;
|
---|
61 | procedure SetByteArray(AData: TArrayOfByte; ASize: TBigIntSize);
|
---|
62 | procedure GetByteArray(var AData: TArrayOfByte; ASize: TBigIntSize);
|
---|
63 | function Copy(Size: TBigIntSize): TBigInt; overload;
|
---|
64 | function Copy: TBigInt; overload;
|
---|
65 | property Size: TBigIntSize read GetSize write SetSize;
|
---|
66 | property Data[Index: TBigIntSize]: Byte read GetData write SetData;
|
---|
67 | end;
|
---|
68 |
|
---|
69 | function TryStrToBigInt(const S: string; out I: TBigInt): Boolean;
|
---|
70 | function IntToStr(Value: TBigInt): string; overload;
|
---|
71 | function IntToHex(Value: TBigInt): string; overload;
|
---|
72 | function IntToHex(Value: TBigInt; Digits: Integer): string; overload;
|
---|
73 |
|
---|
74 |
|
---|
75 | implementation
|
---|
76 |
|
---|
77 | resourcestring
|
---|
78 | SUnsupportedByteSize = 'Unsupported byte size';
|
---|
79 | SOutOfRange = 'Out of range';
|
---|
80 |
|
---|
81 | const
|
---|
82 | HexDigits: array[0..15] of Char = '0123456789ABCDEF';
|
---|
83 |
|
---|
84 | function TryStrToBigInt(const S: string; out I: TBigInt): Boolean;
|
---|
85 | var
|
---|
86 | Value: Int64;
|
---|
87 | begin
|
---|
88 | Result := TryStrToInt64(S, Value);
|
---|
89 | I := Value;
|
---|
90 | end;
|
---|
91 |
|
---|
92 | function IntToHex(Value: TBigInt): string;
|
---|
93 | begin
|
---|
94 | Result := '';
|
---|
95 | while Value <> 0 do begin
|
---|
96 | Result := HexDigits[Value and 15] + Result;
|
---|
97 | Value := Value shr 4;
|
---|
98 | end;
|
---|
99 | if Result = '' then Result := '0';
|
---|
100 | end;
|
---|
101 |
|
---|
102 | function IntToHex(Value: TBigInt; Digits: Integer): string;
|
---|
103 | var
|
---|
104 | I: Integer;
|
---|
105 | begin
|
---|
106 | if Digits = 0 then
|
---|
107 | Digits := 1;
|
---|
108 | Result := '';
|
---|
109 | SetLength(Result, Digits);
|
---|
110 | for I := 0 to Digits - 1 do
|
---|
111 | begin
|
---|
112 | Result[Digits - I] := HexDigits[Value and 15];
|
---|
113 | Value := Value shr 4;
|
---|
114 | end ;
|
---|
115 | while Value <> 0 do begin
|
---|
116 | Result := HexDigits[Value and 15] + Result;
|
---|
117 | Value := Value shr 4;
|
---|
118 | end;
|
---|
119 | end;
|
---|
120 |
|
---|
121 | function IntToStr(Value: TBigInt): string;
|
---|
122 | begin
|
---|
123 | Result := '';
|
---|
124 | if Value < 0 then begin
|
---|
125 | Value := -Value;
|
---|
126 | while Value > 9 do begin
|
---|
127 | Result := Chr(Ord('0') + (Value mod 10)) + Result;
|
---|
128 | Value := Value div 10;
|
---|
129 | end;
|
---|
130 | Result := '-' + Chr(Ord('0') + (Value mod 10)) + Result;
|
---|
131 | end else begin
|
---|
132 | while Value > 9 do begin
|
---|
133 | Result := Chr(Ord('0') + (Value mod 10)) + Result;
|
---|
134 | Value := Value div 10;
|
---|
135 | end;
|
---|
136 | Result := Chr(Ord('0') + Value) + Result;
|
---|
137 | end;
|
---|
138 | end;
|
---|
139 |
|
---|
140 | { TBigInt }
|
---|
141 |
|
---|
142 | function TBigInt.GetSize: TBigIntSize;
|
---|
143 | begin
|
---|
144 | Result := Length(FData);
|
---|
145 | end;
|
---|
146 |
|
---|
147 | function TBigInt.GetData(Index: TBigIntSize): Byte;
|
---|
148 | begin
|
---|
149 | if Index < Size then Result := FData[Index]
|
---|
150 | else Result := 0;
|
---|
151 | end;
|
---|
152 |
|
---|
153 | procedure TBigInt.SetData(Index: TBigIntSize; AValue: Byte);
|
---|
154 | begin
|
---|
155 | if Index >= Integer(Size) then raise Exception.Create(SOutOfRange);
|
---|
156 | FData[Index] := AValue;
|
---|
157 | end;
|
---|
158 |
|
---|
159 | procedure TBigInt.SetSize(AValue: TBigIntSize);
|
---|
160 | var
|
---|
161 | LastSize: TBigIntSize;
|
---|
162 | begin
|
---|
163 | LastSize := GetSize;
|
---|
164 | SetLength(FData, AValue);
|
---|
165 | if AValue > LastSize then
|
---|
166 | FillChar(FData[LastSize], AValue - LastSize, 0);
|
---|
167 | end;
|
---|
168 |
|
---|
169 | class operator TBigInt.Implicit(A: Byte): TBigInt;
|
---|
170 | begin
|
---|
171 | Result.Size := 1;
|
---|
172 | Result.FData[0] := A;
|
---|
173 | end;
|
---|
174 |
|
---|
175 | class operator TBigInt.Implicit(A: Word): TBigInt;
|
---|
176 | begin
|
---|
177 | Result.Size := 2;
|
---|
178 | PWord(@Result.FData[0])^ := A;
|
---|
179 | Result.Shrink;
|
---|
180 | end;
|
---|
181 |
|
---|
182 | class operator TBigInt.Implicit(A: ShortInt): TBigInt;
|
---|
183 | begin
|
---|
184 | Result.Size := 1;
|
---|
185 | PByte(@Result.FData[0])^ := A;
|
---|
186 | Result.Shrink;
|
---|
187 | end;
|
---|
188 |
|
---|
189 | class operator TBigInt.Implicit(A: Integer): TBigInt;
|
---|
190 | begin
|
---|
191 | Result.Size := 4;
|
---|
192 | PInteger(@Result.FData[0])^ := A;
|
---|
193 | Result.Shrink;
|
---|
194 | end;
|
---|
195 |
|
---|
196 | class operator TBigInt.Implicit(A: QWord): TBigInt;
|
---|
197 | begin
|
---|
198 | Result.Size := 8;
|
---|
199 | PQWord(@Result.FData[0])^ := A;
|
---|
200 | Result.Shrink;
|
---|
201 | end;
|
---|
202 |
|
---|
203 | class operator TBigInt.Implicit(A: Int64): TBigInt;
|
---|
204 | begin
|
---|
205 | Result.Size := 8;
|
---|
206 | PInt64(@Result.FData[0])^ := A;
|
---|
207 | Result.Shrink;
|
---|
208 | end;
|
---|
209 |
|
---|
210 | class operator TBigInt.Implicit(A: TBigInt): UInt8;
|
---|
211 | begin
|
---|
212 | if A.Size = 1 then Result := A.FData[0]
|
---|
213 | else raise Exception.Create(SUnsupportedByteSize);
|
---|
214 | end;
|
---|
215 |
|
---|
216 | class operator TBigInt.Implicit(A: TBigInt): Int8;
|
---|
217 | begin
|
---|
218 | if A.Size = 1 then Result := A.FData[0]
|
---|
219 | else raise Exception.Create(SUnsupportedByteSize);
|
---|
220 | end;
|
---|
221 |
|
---|
222 | class operator TBigInt.Implicit(A: TBigInt): UInt16;
|
---|
223 | begin
|
---|
224 | if A.Size = 2 then Result := PUInt16(@A.FData[0])^
|
---|
225 | else raise Exception.Create(SUnsupportedByteSize);
|
---|
226 | end;
|
---|
227 |
|
---|
228 | class operator TBigInt.Implicit(A: TBigInt): Int16;
|
---|
229 | begin
|
---|
230 | if A.Size = 2 then Result := PInt16(@A.FData[0])^
|
---|
231 | else raise Exception.Create(SUnsupportedByteSize);
|
---|
232 | end;
|
---|
233 |
|
---|
234 | class operator TBigInt.Implicit(A: TBigInt): Int32;
|
---|
235 | begin
|
---|
236 | case A.Size of
|
---|
237 | 1: Result := PByte(@A.FData[0])^;
|
---|
238 | 2: Result := PWord(@A.FData[0])^;
|
---|
239 | 3: Result := PWord(@A.FData[0])^ or (PByte(@A.FData[2])^ shl 16);
|
---|
240 | 4: Result := PDWord(@A.FData[0])^;
|
---|
241 | 8: Result := PQWord(@A.FData[0])^;
|
---|
242 | else raise Exception.Create(SUnsupportedByteSize);
|
---|
243 | end;
|
---|
244 | end;
|
---|
245 |
|
---|
246 | class operator TBigInt.Implicit(A: TBigInt): UInt32;
|
---|
247 | begin
|
---|
248 | if A.Size = 4 then Result := PInt32(@A.FData[0])^
|
---|
249 | else raise Exception.Create(SUnsupportedByteSize);
|
---|
250 | end;
|
---|
251 |
|
---|
252 | class operator TBigInt.Implicit(A: TBigInt): UInt64;
|
---|
253 | begin
|
---|
254 | if A.Size = 1 then Result := PUInt8(@A.FData[0])^
|
---|
255 | else if A.Size = 2 then Result := PUInt16(@A.FData[0])^
|
---|
256 | else if A.Size = 4 then Result := PUInt32(@A.FData[0])^
|
---|
257 | else if A.Size = 8 then Result := PUInt64(@A.FData[0])^
|
---|
258 | else raise Exception.Create(SUnsupportedByteSize);
|
---|
259 | end;
|
---|
260 |
|
---|
261 | class operator TBigInt.Implicit(A: TBigInt): Int64;
|
---|
262 | begin
|
---|
263 | if A.Size = 1 then Result := PInt8(@A.FData[0])^
|
---|
264 | else if A.Size = 2 then Result := PInt16(@A.FData[0])^
|
---|
265 | else if A.Size = 4 then Result := PInt32(@A.FData[0])^
|
---|
266 | else if A.Size = 8 then Result := PInt64(@A.FData[0])^
|
---|
267 | else raise Exception.Create(SUnsupportedByteSize);
|
---|
268 | end;
|
---|
269 |
|
---|
270 | class operator TBigInt.Implicit(A: TBigInt): PByte;
|
---|
271 | begin
|
---|
272 | if A.Size = 4 then Result := PByte(@PInteger(@A.FData[0])^)
|
---|
273 | else raise Exception.Create(SUnsupportedByteSize);
|
---|
274 | end;
|
---|
275 |
|
---|
276 | class operator TBigInt.Negative(A: TBigInt): TBigInt;
|
---|
277 | begin
|
---|
278 | Result := A.Copy(A.Size);
|
---|
279 | Result.Invert;
|
---|
280 | Result := Result + 1;
|
---|
281 | end;
|
---|
282 |
|
---|
283 | class operator TBigInt.Inc(A: TBigInt): TBigInt;
|
---|
284 | begin
|
---|
285 | Result := A + 1;
|
---|
286 | end;
|
---|
287 |
|
---|
288 | class operator TBigInt.Dec(A: TBigInt): TBigInt;
|
---|
289 | begin
|
---|
290 | Result := A - 1;
|
---|
291 | end;
|
---|
292 |
|
---|
293 | class operator TBigInt.Add(A, B: TBigInt): TBigInt;
|
---|
294 | var
|
---|
295 | I: Integer;
|
---|
296 | V: SmallInt;
|
---|
297 | Carry: Byte;
|
---|
298 | Size: Byte;
|
---|
299 | begin
|
---|
300 | Size := Max(A.Size, B.Size);
|
---|
301 | Result.Size := Size;
|
---|
302 | Carry := 0;
|
---|
303 | I := 0;
|
---|
304 | while (I < Size) or (Carry > 0) do begin
|
---|
305 | if I >= Result.Size then Result.Size := I + 1;
|
---|
306 | V := A.Data[I] + B.Data[I] + Carry;
|
---|
307 | if V >= 256 then begin
|
---|
308 | Carry := 1;
|
---|
309 | end else Carry := 0;
|
---|
310 | Result.Data[I] := V and $ff;
|
---|
311 | Inc(I);
|
---|
312 | end;
|
---|
313 | end;
|
---|
314 |
|
---|
315 | class operator TBigInt.Subtract(A, B: TBigInt): TBigInt;
|
---|
316 | var
|
---|
317 | Size: TBigIntSize;
|
---|
318 | begin
|
---|
319 | Size := Max(A.Size, B.Size);
|
---|
320 | Result := A + -B;
|
---|
321 | Result.Size := Size;
|
---|
322 | Result.Shrink;
|
---|
323 | end;
|
---|
324 |
|
---|
325 | class operator TBigInt.Equal(A, B: TBigInt): Boolean;
|
---|
326 | var
|
---|
327 | I: Byte;
|
---|
328 | begin
|
---|
329 | Result := A.Size = B.Size;
|
---|
330 | if not Result then Exit;
|
---|
331 | for I := 0 to A.Size - 1 do
|
---|
332 | if A.FData[I] <> B.FData[I] then begin
|
---|
333 | Result := False;
|
---|
334 | Break;
|
---|
335 | end;
|
---|
336 | end;
|
---|
337 |
|
---|
338 | class operator TBigInt.NotEqual(A, B: TBigInt): Boolean;
|
---|
339 | var
|
---|
340 | I: Byte;
|
---|
341 | begin
|
---|
342 | Result := A.Size = B.Size;
|
---|
343 | if not Result then Exit;
|
---|
344 | for I := 0 to A.Size - 1 do
|
---|
345 | if A.FData[I] <> B.FData[I] then begin
|
---|
346 | Result := False;
|
---|
347 | Break;
|
---|
348 | end;
|
---|
349 | Result := not Result;
|
---|
350 | end;
|
---|
351 |
|
---|
352 | class operator TBigInt.LessThan(A, B: TBigInt): Boolean;
|
---|
353 | var
|
---|
354 | Temp: TBigInt;
|
---|
355 | begin
|
---|
356 | Temp := A - B;
|
---|
357 | Result := Temp.IsNegative;
|
---|
358 | end;
|
---|
359 |
|
---|
360 | class operator TBigInt.LessThanOrEqual(A, B: TBigInt): Boolean;
|
---|
361 | var
|
---|
362 | Temp: TBigInt;
|
---|
363 | begin
|
---|
364 | Temp := A - B;
|
---|
365 | Result := Temp.IsNegative or Temp.IsZero;
|
---|
366 | end;
|
---|
367 |
|
---|
368 | class operator TBigInt.GreaterThan(A, B: TBigInt): Boolean;
|
---|
369 | var
|
---|
370 | Temp: TBigInt;
|
---|
371 | begin
|
---|
372 | Temp := A - B;
|
---|
373 | Result := Temp.IsPositive and not Temp.IsZero;
|
---|
374 | end;
|
---|
375 |
|
---|
376 | class operator TBigInt.GreaterThanOrEqual(A, B: TBigInt): Boolean;
|
---|
377 | var
|
---|
378 | Temp: TBigInt;
|
---|
379 | begin
|
---|
380 | Temp := A - B;
|
---|
381 | Result := Temp.IsPositive;
|
---|
382 | end;
|
---|
383 |
|
---|
384 | class operator TBigInt.BitwiseXor(A, B: TBigInt): TBigInt;
|
---|
385 | var
|
---|
386 | I: TBigIntSize;
|
---|
387 | begin
|
---|
388 | Result.Size := Max(A.Size, B.Size);
|
---|
389 | for I := 0 to Result.Size - 1 do
|
---|
390 | Result.Data[I] := A.Data[I] xor B.Data[I];
|
---|
391 | Result.Shrink;
|
---|
392 | end;
|
---|
393 |
|
---|
394 | class operator TBigInt.BitwiseAnd(A, B: TBigInt): TBigInt;
|
---|
395 | var
|
---|
396 | I: TBigIntSize;
|
---|
397 | begin
|
---|
398 | Result.Size := Max(A.Size, B.Size);
|
---|
399 | for I := 0 to Result.Size - 1 do
|
---|
400 | Result.Data[I] := A.Data[I] and B.Data[I];
|
---|
401 | Result.Shrink;
|
---|
402 | end;
|
---|
403 |
|
---|
404 | class operator TBigInt.BitwiseOr(A, B: TBigInt): TBigInt;
|
---|
405 | var
|
---|
406 | I: TBigIntSize;
|
---|
407 | begin
|
---|
408 | Result.Size := Max(A.Size, B.Size);
|
---|
409 | for I := 0 to Result.Size - 1 do
|
---|
410 | Result.Data[I] := A.Data[I] or B.Data[I];
|
---|
411 | Result.Shrink;
|
---|
412 | end;
|
---|
413 |
|
---|
414 | class operator TBigInt.LeftShift(A: TBigInt; B: Integer): TBigInt;
|
---|
415 | var
|
---|
416 | ByteShift: TBigIntSize;
|
---|
417 | BitShift: Byte;
|
---|
418 | I: Integer;
|
---|
419 | begin
|
---|
420 | if (B and 7) = 0 then begin
|
---|
421 | // Full byte shift
|
---|
422 | ByteShift := B shr 3;
|
---|
423 | Result.Size := A.Size + ByteShift;
|
---|
424 | Move(A.FData[0], Result.FData[ByteShift], A.Size);
|
---|
425 | FillChar(Result.FData[0], ByteShift, 0);
|
---|
426 | end else begin
|
---|
427 | // Partial byte shift
|
---|
428 | ByteShift := B shr 3;
|
---|
429 | BitShift := B - ByteShift;
|
---|
430 | Result.Size := Result.Size + ByteShift + 1;
|
---|
431 | for I := 0 to A.Size - 1 do begin
|
---|
432 | Result.FData[I + ByteShift] := (A.FData[I] shl BitShift) and $ff;
|
---|
433 | if I > 0 then Result.FData[I + ByteShift] := Result.FData[I + ByteShift] or (A.FData[I] shl BitShift shl 8);
|
---|
434 | end;
|
---|
435 | end;
|
---|
436 | Result.Shrink;
|
---|
437 | end;
|
---|
438 |
|
---|
439 | class operator TBigInt.RightShift(A: TBigInt; B: Integer): TBigInt;
|
---|
440 | var
|
---|
441 | ByteShift: TBigIntSize;
|
---|
442 | BitShift: Byte;
|
---|
443 | I: Integer;
|
---|
444 | begin
|
---|
445 | if (B and 7) = 0 then begin
|
---|
446 | // Full byte shift
|
---|
447 | ByteShift := B shr 3;
|
---|
448 | Result.Size := A.Size - ByteShift;
|
---|
449 | Move(A.FData[ByteShift], Result.FData[0], A.Size);
|
---|
450 | end else begin
|
---|
451 | // Partial byte shift
|
---|
452 | ByteShift := B shr 3;
|
---|
453 | BitShift := B - ByteShift;
|
---|
454 | Result.Size := Result.Size - ByteShift;
|
---|
455 | for I := 0 to A.Size - 1 do begin
|
---|
456 | Result.FData[I] := (A.FData[I + ByteShift] shr BitShift) and $ff;
|
---|
457 | if I < (A.Size - 1) then Result.FData[I] := Result.FData[I] or (((A.FData[I + ByteShift] shl 8) shr BitShift) and $ff);
|
---|
458 | end;
|
---|
459 | end;
|
---|
460 | Result.Shrink;
|
---|
461 | end;
|
---|
462 |
|
---|
463 | class operator TBigInt.Modulus(A, B: TBigInt): TBigInt;
|
---|
464 | begin
|
---|
465 |
|
---|
466 | end;
|
---|
467 |
|
---|
468 | class operator TBigInt.IntDivide(A, B: TBigInt): TBigInt;
|
---|
469 | begin
|
---|
470 |
|
---|
471 | end;
|
---|
472 |
|
---|
473 | procedure TBigInt.Shrink;
|
---|
474 | var
|
---|
475 | I: Byte;
|
---|
476 | begin
|
---|
477 | I := Size - 1;
|
---|
478 | while (I > 0) and (FData[I] = 0) do
|
---|
479 | Dec(I);
|
---|
480 | Size := I + 1;
|
---|
481 | end;
|
---|
482 |
|
---|
483 | function TBigInt.IsNegative: Boolean;
|
---|
484 | begin
|
---|
485 | Result := (FData[Size - 1] and $80) = $80;
|
---|
486 | end;
|
---|
487 |
|
---|
488 | function TBigInt.IsZero: Boolean;
|
---|
489 | var
|
---|
490 | I: TBigIntSize;
|
---|
491 | begin
|
---|
492 | Result := True;
|
---|
493 | for I := 0 to Size - 1 do
|
---|
494 | if FData[I] <> 0 then begin
|
---|
495 | Result := False;
|
---|
496 | Break;
|
---|
497 | end;
|
---|
498 | end;
|
---|
499 |
|
---|
500 | function TBigInt.IsPositive: Boolean;
|
---|
501 | begin
|
---|
502 | Result := (FData[Size - 1] and $80) = 0;
|
---|
503 | end;
|
---|
504 |
|
---|
505 | procedure TBigInt.Invert;
|
---|
506 | var
|
---|
507 | I: Byte;
|
---|
508 | begin
|
---|
509 | for I := 0 to Size - 1 do
|
---|
510 | FData[I] := FData[I] xor $ff;
|
---|
511 | end;
|
---|
512 |
|
---|
513 | procedure TBigInt.SetByteArray(AData: TArrayOfByte; ASize: TBigIntSize);
|
---|
514 | begin
|
---|
515 | Size := ASize;
|
---|
516 | Move(AData[0], FData[0], Size);
|
---|
517 | end;
|
---|
518 |
|
---|
519 | procedure TBigInt.GetByteArray(var AData: TArrayOfByte; ASize: TBigIntSize);
|
---|
520 | begin
|
---|
521 | SetLength(AData, ASize);
|
---|
522 | Move(FData[0], AData[0], Size);
|
---|
523 | end;
|
---|
524 |
|
---|
525 | function TBigInt.Copy(Size: TBigIntSize): TBigInt;
|
---|
526 | begin
|
---|
527 | Result.Size := Size;
|
---|
528 | case Result.Size of
|
---|
529 | 1: PByte(@Result.FData[0])^ := PByte(@FData[0])^;
|
---|
530 | 2: PWord(@Result.FData[0])^ := PWord(@FData[0])^;
|
---|
531 | 4: PDWord(@Result.FData[0])^ := PDWord(@FData[0])^;
|
---|
532 | 8: PQWord(@Result.FData[0])^ := PQWord(@FData[0])^;
|
---|
533 | else Move(PByte(@FData[0])^, PByte(@Result.FData[0])^, Size);
|
---|
534 | end;
|
---|
535 | end;
|
---|
536 |
|
---|
537 | function TBigInt.Copy: TBigInt;
|
---|
538 | begin
|
---|
539 | Result := Copy(Size);
|
---|
540 | end;
|
---|
541 |
|
---|
542 | end.
|
---|
543 |
|
---|