MathgeomGLS

Форк
0
/
Velthuis.Numerics.pas 
809 строк · 20.0 Кб
1
{---------------------------------------------------------------------------}
2
{                                                                           }
3
{ File:       Velthuis.Numerics.pas                                         }
4
{ Function:   Integer tool functions.                                       }
5
{ Language:   Delphi version XE3 or later                                   }
6
{ Author:     Rudy Velthuis                                                 }
7
{ Copyright:  (c) 2016 Rudy Velthuis                                        }
8
{                                                                           }
9
{ License:    Redistribution and use in source and binary forms, with or    }
10
{             without modification, are permitted provided that the         }
11
{             following conditions are met:                                 }
12
{                                                                           }
13
{             * Redistributions of source code must retain the above        }
14
{               copyright notice, this list of conditions and the following }
15
{               disclaimer.                                                 }
16
{             * Redistributions in binary form must reproduce the above     }
17
{               copyright notice, this list of conditions and the following }
18
{               disclaimer in the documentation and/or other materials      }
19
{               provided with the distribution.                             }
20
{                                                                           }
21
{ Disclaimer: THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER "AS IS"     }
22
{             AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT     }
23
{             LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND     }
24
{             FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO        }
25
{             EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE     }
26
{             FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,     }
27
{             OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,      }
28
{             PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,     }
29
{             DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED    }
30
{             AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT   }
31
{             LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)        }
32
{             ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF   }
33
{             ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.                    }
34
{                                                                           }
35
{---------------------------------------------------------------------------}
36

37
unit Velthuis.Numerics;
38

39
interface
40

41
// For Delphi XE3 and up:
42
{$IF CompilerVersion >= 24.0 }
43
  {$LEGACYIFEND ON}
44
{$IFEND}
45

46
// For Delphi XE and up:
47
{$IF CompilerVersion >= 22.0}
48
  {$CODEALIGN 16}
49
  {$ALIGN 16}
50
{$IFEND}
51

52
{$INLINE AUTO}
53

54
uses
55
  System.Math;
56

57
// Return the number of set (1) bits in the given integers.
58
function BitCount(U: UInt8): Integer; overload;
59
function BitCount(U: UInt16): Integer; overload;
60
function BitCount(S: Int32): Integer; overload;
61
function BitCount(U: UInt32): Integer; overload;
62
function BitCount(S: Int64): Integer; overload;
63
function BitCount(S: UInt64): Integer; overload;
64

65
// Return the number of significant bits, excluding the sign bit.
66
function BitLength(S: Int32): Integer; overload;
67
function BitLength(U: UInt32): Integer; overload;
68
function BitLength(S: Int64): Integer; overload;
69
function BitLength(U: UInt64): Integer; overload;
70

71
// Return the number of significant digits.
72
function DigitCount(S: Int32): Int32; overload;
73
function DigitCount(U: UInt32): UInt32; overload;
74

75
// Return an integer value with at most a single one-bit, in the position
76
// of the most significant one-bit in the specified integer value.
77
function HighestOneBit(S: Int32): Int32; overload;
78
function HighestOneBit(U: UInt32): UInt32; overload;
79

80
// Checks if the given integer is a power of two.
81
function IsPowerOfTwo(S: Int32): Boolean; overload;
82
function IsPowerOfTwo(U: UInt32): Boolean; overload;
83

84
// Return an integer value with at most a single one-bit, in the position
85
// of the least significant one-bit in the given integers value.
86
function LowestOneBit(S: Int32): Int32; overload;
87
function LowestOneBit(U: UInt32): UInt32; overload;
88

89
// Return the number of leading (high order) zero-bits (excluding the sign bit) of
90
// the given integers.
91
function NumberOfLeadingZeros(U: UInt16): Integer; overload;
92
function NumberOfLeadingZeros(S: Int32): Integer; overload;
93
function NumberOfLeadingZeros(U: UInt32): Integer; overload;
94
function NumberOfLeadingZeros(S: Int64): Integer; overload;
95
function NumberOfLeadingZeros(U: UInt64): Integer; overload;
96

97
// Return the number of trailing (low order) zero-bits of the given integers.
98
function NumberOfTrailingZeros(U: UInt32): Integer; overload;
99
function NumberOfTrailingZeros(U: UInt64): Integer; overload;
100

101
// Reverse the bits of the given integers.
102
function Reverse(U: UInt8): UInt8; overload;
103
function Reverse(U: UInt16): UInt16; overload;
104
function Reverse(S: Int32): Int32; overload;
105
function Reverse(U: UInt32): UInt32; overload;
106

107
// Reverse the bytes of the given integers.
108
function ReverseBytes(S: Int32): Int32; overload;
109
function ReverseBytes(U: UInt32): UInt32; overload;
110

111
// Rotate the given integers left by Distance bits.
112
function RotateLeft(S: Int32; Distance: Integer): Int32; overload;
113
function RotateLeft(U: UInt32; Distance: Integer): UInt32; overload;
114

115
// Rotate the given integers right by Distance bits.
116
function RotateRight(S: Int32; Distance: Integer): Int32; overload;
117
function RotateRight(U: UInt32; Distance: Integer): UInt32; overload;
118

119
// Returns the sign of the integer: -1 for negative, 0 for zero and 1 for positive.
120
function Sign(S: Int32): TValueSign;
121

122
// Return a binary representation of the given integers.
123
function ToBinaryString(S: Int32): string; overload;
124
function ToBinaryString(U: UInt32): string; overload;
125

126
// Return a hexadecimal representation of the given integers.
127
function ToHexString(S: Int32): string; overload;
128
function ToHexString(U: UInt32): string; overload;
129

130
// Return an octal representation of the given integers.
131
function ToOctalString(S: Int32): string; overload;
132
function ToOctalString(U: UInt32): string; overload;
133

134
// Return a string representation of the given integers, in the given numerical base.
135
function ToString(S: Int32; Base: Byte): string; overload;
136
function ToString(U: UInt32; Base: Byte): string; overload;
137
function ToString(S: Int32): string; overload;
138
function ToString(U: UInt32): string; overload;
139

140
// Compare the given integers and return -1 for less, 0 for equal and 1 for greater.
141
function Compare(Left, Right: Int32): Integer; overload;
142
function Compare(Left, Right: UInt32): Integer; overload;
143
function Compare(Left, Right: Int64): Integer; overload;
144
function Compare(Left, Right: UInt64): Integer; overload;
145

146
// Calculate a hash code for the given integers.
147
function HashCode(Value: Int32): UInt32; overload;
148
function HashCode(Value: UInt32): UInt32; overload;
149
function HashCode(Value: Int64): UInt32; overload;
150
function HashCode(Value: UInt64): UInt32; overload;
151

152
implementation
153

154

155
uses
156
  System.SysUtils, Velthuis.StrConsts;
157

158
// https://en.wikipedia.org/wiki/Find_first_set
159

160
const
161
  // Currently not used.
162
  NLZDeBruijn32Mult = $07C4ACDD;
163
  NLZDeBruijn32: array[0..31] of Byte =
164
  (
165
    31, 22, 30, 21, 18, 10, 29,  2, 20, 17, 15, 13,  9,  6, 28,  1,
166
    23, 19, 11,  3, 16, 14,  7, 24, 12,  4,  8, 25,  5, 26, 27,  0
167
  );
168

169
  NTZDeBruijn32Mult = $077CB531;
170
  NTZDeBruijn32: array[0..31] of Byte =
171
  (
172
     0,  1, 28,  2, 29, 14, 24,  3, 30, 22, 20, 15, 25, 17,  4,  8,
173
    31, 27, 13, 23, 21, 19, 16,  7, 26, 12, 18,  6, 11,  5, 10,  9
174
  );
175

176
  BitCounts: array[0..15] of Byte = (0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4);
177

178
function BitCount(U: UInt8): Integer;
179
begin
180
  Result := BitCounts[U and $0F] + BitCounts[U shr 4];
181
end;
182

183
function BitCount(U: UInt16): Integer;
184
{$IF DEFINED(WIN32)}
185
asm
186
        MOV     DX,AX
187
        SHR     DX,1
188
        AND     DX,$5555
189
        SUB     AX,DX
190
        MOV     DX,AX
191
        AND     AX,$3333
192
        SHR     DX,2
193
        AND     DX,$3333
194
        ADD     AX,DX
195
        MOV     DX,AX
196
        SHR     DX,4
197
        ADD     AX,DX
198
        AND     AX,$0F0F
199
        MOV     DX,AX
200
        SHR     AX,8
201
        ADD     AX,DX
202
        AND     EAX,$7F
203
end;
204
{$ELSEIF DEFINED(WIN64)}
205
asm
206
        .NOFRAME
207

208
        MOV     AX,CX
209
        SHR     CX,1
210
        AND     CX,$5555
211
        SUB     AX,CX
212
        MOV     CX,AX
213
        AND     AX,$3333
214
        SHR     CX,2
215
        AND     CX,$3333
216
        ADD     AX,CX
217
        MOV     CX,AX
218
        SHR     CX,4
219
        ADD     AX,CX
220
        AND     AX,$0F0F
221
        MOV     CX,AX
222
        SHR     AX,8
223
        ADD     AX,CX
224
        AND     EAX,$7F
225
end;
226
{$ELSE PUREPASCAL}
227
begin
228
  U := U - ((U shr 1) and $5555);
229
  U := (U and $3333) + ((U shr 2) and $3333);
230
  U := (U + (U shr 4)) and $0F0F;
231
  U := U + (U shr 8);
232
  Result := U and $7F;
233
end;
234
{$IFEND PUREPASCAL}
235

236
function BitCount(S: Int32): Integer;
237
begin
238
  Result := BitCount(UInt32(S));
239
end;
240

241
// Faster than 16 bit table lookups
242
function BitCount(U: UInt32): Integer;
243
{$IF DEFINED(WIN32)}
244
asm
245
        MOV     EDX,EAX
246
        SHR     EDX,1
247
        AND     EDX,$55555555
248
        SUB     EAX,EDX
249
        MOV     EDX,EAX
250
        AND     EAX,$33333333
251
        SHR     EDX,2
252
        AND     EDX,$33333333
253
        ADD     EAX,EDX
254
        MOV     EDX,EAX
255
        SHR     EDX,4
256
        ADD     EAX,EDX
257
        AND     EAX,$0F0F0F0F
258
        MOV     EDX,EAX
259
        SHR     EAX,8
260
        ADD     EAX,EDX
261
        MOV     EDX,EAX
262
        SHR     EDX,16
263
        ADD     EAX,EDX
264
        AND     EAX,$7F
265
end;
266
{$ELSEIF DEFINED(WIN64)}
267
asm
268
        .NOFRAME
269

270
        MOV     EAX,ECX
271
        SHR     ECX,1
272
        AND     ECX,$55555555
273
        SUB     EAX,ECX
274
        MOV     ECX,EAX
275
        AND     EAX,$33333333
276
        SHR     ECX,2
277
        AND     ECX,$33333333
278
        ADD     EAX,ECX
279
        MOV     ECX,EAX
280
        SHR     ECX,4
281
        ADD     EAX,ECX
282
        AND     EAX,$0F0F0F0F
283
        MOV     ECX,EAX
284
        SHR     EAX,8
285
        ADD     EAX,ECX
286
        MOV     ECX,EAX
287
        SHR     ECX,16
288
        ADD     EAX,ECX
289
        AND     EAX,$7F
290
end;
291
{$ELSE PUREPASCAL}
292
begin
293
  U := U - ((U shr 1) and $55555555);
294
  U := (U and $33333333) + ((U shr 2) and $33333333);
295
  U := (U + (U shr 4)) and $0F0F0F0F;
296
  U := U + (U shr 8);
297
  U := U + (U shr 16);
298
  Result := U and $7F;
299
end;
300
{$IFEND PUREPASCAL}
301

302
function BitCount(S: Int64): Integer; overload;
303
begin
304
  Result := BitCount(UInt32(S)) + BitCount(Int32(S shr 32));
305
end;
306

307
function BitCount(S: UInt64): Integer; overload;
308
begin
309
  Result := BitCount(UInt32(S)) + BitCount(UInt32(S shr 32));
310
end;
311

312
function BitLength(S: Int32): Integer;
313
begin
314
  Result := BitLength(UInt32(S));
315
end;
316

317
function BitLength(U: UInt32): Integer;
318
begin
319
  Result := 32 - NumberOfLeadingZeros(U);
320
end;
321

322
function BitLength(S: Int64): Integer;
323
begin
324
  Result := 64 - NumberOfLeadingZeros(S);
325
end;
326

327
function BitLength(U: UInt64): Integer;
328
begin
329
  Result := 64 - NumberOfLeadingZeros(U);
330
end;
331

332
function DigitCount(S: Int32): Int32; overload;
333
begin
334
  if S <> Low(Int32) then
335
    Result := DigitCount(UInt32(Abs(S)))
336
  else
337
    Result := 9;
338
end;
339

340
function DigitCount(U: UInt32): UInt32; overload;
341
begin
342
  Result := 1;
343
  if U >= 100000000 then
344
  begin
345
    Inc(Result, 8);
346
    U := U div 100000000;
347
  end;
348
  if U >= 10000 then
349
  begin
350
    Inc(Result, 4);
351
    U := U div 10000;
352
  end;
353
  if U >= 100  then
354
  begin
355
    Inc(Result, 2);
356
    U := U div 100;
357
  end;
358
  if U >= 10 then
359
    Inc(Result);
360
end;
361

362
function IsPowerOfTwo(S: Int32): Boolean;
363
begin
364
  if S <> Low(Int32) then
365
    Result := IsPowerofTwo(UInt32(Abs(S)))
366
  else
367
    Result := True;
368
end;
369

370
function IsPowerOfTwo(U: UInt32): Boolean;
371
begin
372
  Result := (U and (U - 1)) = 0;
373
end;
374

375
function HighestOneBit(S: Int32): Int32;
376
begin
377
  Result := Int32(HighestOneBit(UInt32(S)));
378
end;
379

380
function HighestOneBit(U: UInt32): UInt32;
381
begin
382
  if U = 0 then
383
    Result := 0
384
  else
385
    Result := UInt32(1) shl (31 - NumberOfLeadingZeros(U));
386
end;
387

388
function LowestOneBit(S: Int32): Int32;
389
begin
390
  Result := Int32(LowestOneBit(UInt32(S)));
391
end;
392

393
function LowestOneBit(U: UInt32): UInt32;
394
begin
395
  Result := U and -Int32(U);
396
end;
397

398
function NumberOfLeadingZeros(U: UInt16): Integer;
399
{$IF DEFINED(WIN32)}
400
asm
401
        MOVZX   EAX,AX
402
        BSR     EDX,EAX
403
        JNZ     @Invert
404
        MOV     EAX,16
405
        RET
406

407
@Invert:
408

409
        MOV     EAX,15
410
        SUB     EAX,EDX
411
end;
412
{$ELSEIF DEFINED(WIN64)}
413
asm
414
        .NOFRAME
415

416
        MOVZX   EAX,CX
417
        BSR     ECX,EAX
418
        JNZ     @Invert
419
        MOV     EAX,16
420
        RET
421

422
@Invert:
423

424
        MOV     EAX,15
425
        SUB     EAX,ECX
426
end;
427
{$ELSE PUREPASCAL}
428
begin
429
  if U = 0 then
430
    Result := 16
431
  else
432
  begin
433
    Result := 0;
434
    if U <= High(Word) shr 8 then
435
    begin
436
      Result := Result + 8;
437
      U := U shl 8;
438
    end;
439
    if U <= High(Word) shr 4 then
440
    begin
441
      Result := Result + 4;
442
      U := U shl 4;
443
    end;
444
    if U <= High(Word) shr 2 then
445
    begin
446
      Result := Result + 2;
447
      U := U shl 2;
448
    end;
449
    if U <= High(Word) shr 1 then
450
      Result := Result + 1;
451
  end;
452
end;
453
{$IFEND PUREPASCAL}
454

455
function NumberOfLeadingZeros(S: Int32): Integer;
456
begin
457
  Result := NumberOfLeadingZeros(UInt32(Abs(S)));
458
end;
459

460
function NumberOfLeadingZeros(U: UInt32): Integer;
461
{$IF DEFINED(WIN32)}
462
asm
463
        BSR     EDX,EAX
464
        JNZ     @Invert
465
        MOV     EAX,32
466
        RET
467

468
@Invert:
469

470
        MOV     EAX,31
471
        SUB     EAX,EDX
472

473
@Exit:
474
end;
475
{$ELSEIF DEFINED(WIN64)}
476
asm
477
         .NOFRAME
478

479
         BSR    EDX,ECX
480
         JNZ    @Invert
481
         MOV    EAX,32
482
         RET
483

484
@Invert:
485

486
         MOV    EAX,31
487
         SUB    EAX,EDX
488

489
@Exit:
490
end;
491
{$ELSE PUREPASCAL}
492

493
// Faster than X := X or X shr 1..16; Result := NLZDeBruijn32[...];
494

495
begin
496
  if U = 0 then
497
    Result := 32
498
  else
499
  begin
500
    Result := 0;
501
    if U <= High(Cardinal) shr 16 then
502
    begin
503
      Result := Result + 16;
504
      U := U shl 16;
505
    end;
506
    if U <= High(Cardinal) shr 8 then
507
    begin
508
      Result := Result + 8;
509
      U := U shl 8;
510
    end;
511
    if U <= High(Cardinal) shr 4 then
512
    begin
513
      Result := Result + 4;
514
      U := U shl 4;
515
    end;
516
    if U <= High(Cardinal) shr 2 then
517
    begin
518
      Result := Result + 2;
519
      U := U shl 2;
520
    end;
521
    if U <= High(Cardinal) shr 1 then
522
      Result := Result + 1;
523
  end;
524
end;
525
{$IFEND PUREPASCAL}
526

527
function NumberOfLeadingZeros(S: Int64): Integer;
528
begin
529
  Result := NumberOfLeadingZeros(UInt64(Abs(S)));
530
end;
531

532
function NumberOfLeadingZeros(U: UInt64): Integer;
533
begin
534
  if U = 0 then
535
    Exit(1);
536
  if U <= High(UInt32) then
537
    Result := NumberOfLeadingZeros(UInt32(U)) + 32
538
  else
539
    Result := NumberOfLeadingZeros(UInt32(U shr 32));
540
end;
541

542
// Faster than NumberOfTrailingZeros2().
543
function NumberOfTrailingZeros(U: UInt32): Integer;
544
{$IF DEFINED(WIN32)}
545
asm
546
        BSF     EAX,EAX
547
        JNZ     @Exit
548
        MOV     EAX,32
549

550
@Exit:
551
end;
552
{$ELSEIF DEFINED(WIN64)}
553
asm
554
        .NOFRAME
555

556
        BSF     EAX,ECX
557
        JNZ     @Exit
558
        MOV     EAX,32
559

560
@Exit:
561
end;
562
{$ELSE PUREPASCAL}
563
begin
564
  if U = 0 then
565
    Result := 32
566
  else
567
    Result := NTZDeBruijn32[((U and (-Integer(U))) * NTZDeBruijn32Mult) shr 27];
568
end;
569
{$IFEND PUREPASCAL}
570

571
function NumberOfTrailingZeros(U: UInt64): Integer;
572
{$IF DEFINED(WIN32)}
573
asm
574
        BSF    EAX,DWORD PTR [U]
575
        JNZ    @Exit
576
        BSF    EAX,DWORD PTR [U+TYPE DWORD]
577
        JZ     @Ret64
578
        ADD    EAX,32
579
        JMP    @Exit
580
@Ret64:
581
        MOV    EAX,64
582
@Exit:
583
end;
584
{$ELSEIF DEFINED(WIN64)}
585
asm
586
        .NOFRAME
587

588
        BSF    RAX,RCX
589
        JNZ    @Exit
590
        MOV    EAX,64
591
@Exit:
592
end;
593
{$ELSE PUREPASCAL}
594
type
595
  TUInt64 = packed record
596
    Lo, Hi: UInt32;
597
  end;
598
begin
599
  if UInt32(U) = 0 then
600
    Result := 32 + NumberOfTrailingZeros(TUInt64(U).Hi)
601
  else
602
    Result := NumberOfTrailingZeros(UInt32(U));
603
end;
604
{$IFEND PUREPASCAL}
605

606
function Reverse(U: UInt8): UInt8;
607
begin
608
  U := ((U shr 1) and $55) or ((U and $55) shl 1);
609
  U := ((U shr 2) and $33) or ((U and $33) shl 2);
610
  U := (U shr 4) or (U shl 4);
611
  Result := U;
612
end;
613

614
function Reverse(U: UInt16): UInt16;
615
begin
616
  U := ((U shr 1) and $5555) or ((U and $5555) shl 1);
617
  U := ((U shr 2) and $3333) or ((U and $3333) shl 2);
618
  U := ((U shr 4) and $0F0F) or ((U and $0F0F) shl 4);
619
  U := Swap(U);
620
  Result := U;
621
end;
622

623
function Reverse(S: Int32): Int32;
624
begin
625
  Result := Int32(Reverse(UInt32(S)));
626
end;
627

628
// See http://stackoverflow.com/questions/746171/best-algorithm-for-bit-reversal-from-msb-lsb-to-lsb-msb-in-c too.
629
// http://stackoverflow.com/a/9144870/95954
630
function Reverse(U: UInt32): UInt32;
631
begin
632
  U := ((U shr 1) and $55555555) or ((U and $55555555) shl 1);  // Swap adjacent bits.
633
  U := ((U shr 2) and $33333333) or ((U and $33333333) shl 2);  // Swap adjacent bit pairs.
634
  U := ((U shr 4) and $0F0F0F0F) or ((U and $0F0F0F0F) shl 4);  // Swap nibbles.
635
  U := ((U shr 8) and $00FF00FF) or ((U and $00FF00FF) shl 8);  // Swap bytes.
636
  U := (U shr 16) or (U shl 16);                                // Swap words.
637
  Result := U;
638
end;
639

640
function ReverseBytes(S: Int32): Int32;
641
begin
642
  Result := Int32(ReverseBytes(UInt32(S)));
643
end;
644

645
// Byte and word swaps of Reverse(U).
646
function ReverseBytes(U: UInt32): UInt32;
647
begin
648
  U := ((U shr 8) and $00FF00FF) or ((U and $00FF00FF) shl 8);  // Swap bytes.
649
  U := (U shr 16) or (U shl 16);                                // Swap words.
650
  Result := U;
651
end;
652

653
function RotateLeft(S: Int32; Distance: Integer): Int32;
654
begin
655
  Result := Int32(RotateLeft(UInt32(S), Distance));
656
end;
657

658
function RotateLeft(U: UInt32; Distance: Integer): UInt32;
659
begin
660
  Distance := Distance and 31;
661
  Result := (U shl Distance) or (U shr (32 - Distance));
662
end;
663

664
function RotateRight(S: Int32; Distance: Integer): Int32;
665
begin
666
  Result := Int32(RotateRight(UInt32(S), Distance));
667
end;
668

669
function RotateRight(U: UInt32; Distance: Integer): UInt32;
670
begin
671
  Distance := Distance and 31;
672
  Result := (U shr Distance) or (U shl (32- Distance));
673
end;
674

675
function Sign(S: Int32): TValueSign;
676
begin
677
  Result := System.Math.Sign(S);
678
end;
679

680
function ToBinaryString(S: Int32): string;
681
begin
682
  Result := ToString(S, 2);
683
end;
684

685
function ToBinaryString(U: UInt32): string;
686
begin
687
  Result := ToString(U, 2);
688
end;
689

690
function ToHexString(S: Int32): string;
691
begin
692
  Result := ToString(S, 16);
693
end;
694

695
function ToHexString(U: UInt32): string;
696
begin
697
  Result := ToString(U, 16);
698
end;
699

700
function ToOctalString(S: Int32): string;
701
begin
702
  Result := ToString(S, 8);
703
end;
704

705
function ToOctalString(U: UInt32): string;
706
begin
707
  Result := ToString(U, 8);
708
end;
709

710
const
711
  Digits: array[0..35] of Char = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ';
712

713
function ToString(S: Int32; Base: Byte): string;
714
begin
715
  if S < 0 then
716
    Result := '-' + ToString(UInt32(Abs(S)), Base)
717
  else
718
    Result := ToString(UInt32(S), Base);
719
end;
720

721
function ToString(U: UInt32; Base: Byte): string;
722
begin
723
  if not (Base in [2..36]) then
724
    raise EInvalidArgument.Create(SInvalidArgumentBase);
725

726
  if U = 0 then
727
    Result := '0'
728
  else
729
  begin
730
    Result := '';
731
    while U > 0 do
732
    begin
733
      Result := Digits[U mod Base] + Result;
734
      U := U div Base;
735
    end;
736
  end;
737
end;
738

739
function ToString(S: Int32): string;
740
begin
741
  Result := ToString(S, 10);
742
end;
743

744
function ToString(U: UInt32): string;
745
begin
746
  Result := ToString(U, 10);
747
end;
748

749
function Compare(Left, Right: Int32): Integer;
750
begin
751
  if Left > Right then
752
    Exit(1)
753
  else if Left < Right then
754
    Exit(-1)
755
  else
756
    Exit(0);
757
end;
758

759
function Compare(Left, Right: UInt32): Integer;
760
begin
761
  if Left > Right then
762
    Exit(1)
763
  else if Left < Right then
764
    Exit(-1)
765
  else
766
    Exit(0);
767
end;
768

769
function Compare(Left, Right: Int64): Integer;
770
begin
771
  if Left > Right then
772
    Exit(1)
773
  else if Left < Right then
774
    Exit(-1)
775
  else
776
    Exit(0);
777
end;
778

779
function Compare(Left, Right: UInt64): Integer;
780
begin
781
  if Left > Right then
782
    Exit(1)
783
  else if Left < Right then
784
    Exit(-1)
785
  else
786
    Exit(0);
787
end;
788

789
function HashCode(Value: Int32): UInt32;
790
begin
791
  Result := UInt32(Value);
792
end;
793

794
function HashCode(Value: UInt32): UInt32;
795
begin
796
  Result := Value;
797
end;
798

799
function HashCode(Value: Int64): UInt32;
800
begin
801
  Result := UInt32(Value) xor UInt32(Value shr 32);
802
end;
803

804
function HashCode(Value: UInt64): UInt32;
805
begin
806
  Result := UInt32(Value) xor UInt32(Value shr 32);
807
end;
808

809
end.
810

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.