Data update

This commit is contained in:
Ingy döt Net 2025-06-11 20:16:52 -04:00
parent 72eb4943cb
commit 4d5544505c
2347 changed files with 62432 additions and 16731 deletions

View file

@ -1,32 +1,45 @@
{$mode objFPC}{R+}
FUNCTION Factorial ( n : qword ) : qword;
FUNCTION Fact(n: qword): qword;
(*)
Update for version 3.2.0
Factorial works until 20! , which is good enough for me for now
replace qword with dword and rax,rcx with eax, ecx for 32-bit
for Factorial until 12!
(*)
VAR
F: qword;
VAR
F: qword;
BEGIN
BEGIN
if n > 20 then
begin
WriteLn('This function is only accurate up to 20!');
exit(0);
end;
asm
mov $1, %rax
mov n, %rcx
.Lloop1:
imul %rcx, %rax
loopnz .Lloop1
mov %rax, F
asm
(*) Initialize result = 1 (0! = 1 case handled automatically) (*)
end;
mov $1, %rax (*) RAX = 1 (initial result) (*)
mov n, %rcx (*) RCX = input number (counter) (*)
Result := F ;
END;
test %rcx, %rcx (*) Check if n=0 (*)
jz .Lstore_result (*) Skip loop if n=0 (*)
.Lloop1:
imul %rcx, %rax (*) RAX = RAX * RCX (signed mul) (*)
dec %rcx (*) Decrement RCX (*)
jnz .Lloop1 (*) Loop while RCX != 0 (*)
.Lstore_result:
mov %rax, F (*) Store result in F (*)
end ['rax', 'rcx']; (*) Tell compiler register change (*)
Result := F;
END;
var
N : integer = 20 ;
begin
writeln;
writeln( BasicFact(N));
end. (*) Function Fact (*)

View file

@ -1,92 +1,33 @@
PROGRAM EXBigFac ;
program GMPfact;
{$IFDEF FPC}
{$mode objfpc}{$H+}{$J-}{R+}
{$ELSE}
{$APPTYPE CONSOLE}
{$ENDIF}
{$mode objfpc}
(*)
uses
Free Pascal Compiler version 3.2.0 [2020/06/14] for x86_64
The free and readable alternative at C/C++ speeds
compiles natively to almost any platform, including raspberry PI *
Can run independently from DELPHI / Lazarus
gmp
;
For debian Linux: apt -y install fpc
It contains a text IDE called fp
function Factorial(n: qword): string;
var
ResultMPZ: mpz_t;
i: qword;
begin
mpz_init_set_ui(ResultMPZ, 1);
for i := 2 to n do
mpz_mul_ui(ResultMPZ, ResultMPZ, i);
Result := mpz_get_str(nil, 10, ResultMPZ);
mpz_clear(ResultMPZ);
end;
https://www.freepascal.org/advantage.var
var
N : integer = 101 ;
Fact : string ;
(*)
begin
Fact := Factorial(101);
writeln( N ,'! = ', Fact);
end. (*) GMPfact (*)
USES
gmp;
FUNCTION WriteBigNum ( c: pchar ) : ansistring ;
CONST
CrLf = #13 + #10 ;
VAR
i: longint;
len: longint;
preview: integer;
ret: ansistring = '';
threshold: integer;
BEGIN
len := length ( c ) ;
WriteLn ( 'Digits: ', len ) ;
threshold := 12 ;
preview := len div threshold ;
IF ( len < 91 ) THEN
BEGIN
FOR i := 0 TO len DO
ret:= ret + c [ i ] ;
END
ELSE
BEGIN
FOR i := 0 TO preview DO
ret:= ret + c [ i ] ;
ret:= ret + '...' ;
FOR i := len - preview -1 TO len DO
ret:= ret + c [ i ] ;
END;
ret:= ret + CrLf ;
WriteBigNum := ret;
END;
FUNCTION BigFactorial ( n : qword ) : ansistring ;
(*)
See https://gmplib.org/#DOC
(*)
VAR
S: mpz_t;
c: pchar;
BEGIN
mpz_init_set_ui ( S, 1 ) ;
mpz_fac_ui ( S, n ) ;
c := mpz_get_str ( NIL, 10, S ) ;
BigFactorial := WriteBigNum ( c ) ;
END;
BEGIN
WriteLn ( BigFactorial ( 99 ) ) ;
END.
Output:
Digits: 156
93326215443944...00000000000000
101! = 9425947759838359420851623124482936749562312794702543768327889353416977599316221476503087861591808346911623490003549599583369706302603264000000000000000000000000