•    Free Pascal
• Website
• Downloads
• Wiki
• Bugtracker
• Mailing List
•    Lazarus
• Website
• Downloads (Laz+FPC)
• Packages (OPM)
• FAQ
• Wiki
• Bugtracker
• CCR Bugs
• IRC channel
• GIT
• Mailing List
• Other languages
•    Foundation
• Website
• Project Roadmap
• Getting the Source
• Screenshots
• How to use the forum

### Author Topic: !Num (Number Factorial)  (Read 5487 times)

#### winni ##### Re: !Num (Number Factorial)
« Reply #15 on: July 23, 2021, 05:22:15 pm »

Let's hope is not indeed homework; else we have just helped a student to cheat ... Cheating  wont bring you far in math! That is the difference to buisines studies or jurisprudence.

Winni

#### Kays ##### Re: !Num (Number Factorial)
« Reply #16 on: July 23, 2021, 05:47:35 pm »
Hello, can I do this in pascal: […]
Yes, but there is no built-in support for that, you’ll need—as you already saw—either implement it on your own, or use some sort of library. I haven’t found nothing in the math unit.

with gmp library you can calculate big number and you have a factorial fonction :
Yes, I like that (using GMP). If you like you can also use them good old logarithms, yet it loses precision. On a 64-bit system with an 80-bit FPU, 20! is “already” slightly off.
Code: Pascal  [Select][+][-]
1. program factorialFun(input, output, stdErr);
2.
3. function factorialLn(n: ALUUInt): valReal;
4. begin
5.         factorialLn := 0.0;
6.
7.         for n := n downto 2 do
8.         begin
9.                 factorialLn := factorialLn + ln(n);
10.         end;
11. end;
12.
13. var
14.         n: ALUUInt;
15. begin
16.         for n := 0 to 20 do
17.         begin
18.                 writeLn(n:2, ' : ', round(exp(factorialLn(n))):20);
19.         end;
20. end.
Yet this allows you (to some degree) calculate (or rather approximate) and use factorials that are too large for ALUUInt. Example:
Code: Pascal  [Select][+][-]
1. program lottery(input, output, stdErr);
2.
3. { function factorialLn as defined above }
4.
5. function binomialCoefficient(n, k: ALUUint): ALUUint;
6. begin
7.         binomialCoefficient := round(exp(
8.                         factorialLn(n) -
9.                         (factorialLn(k) + factorialLn(n - k))
10.                 ));
11. end;
12.
13. begin
14.         writeLn('Germany:':20, binomialCoefficient(49, 6):20);
15.         writeLn('US (MM):':20, binomialCoefficient(75, 5):20);
16. end.
NB: There are better algorithms to calculate the binomial coefficient.
Yours Sincerely
Kai Burghardt

#### MarkMLl

• Hero Member
•     • Posts: 3254 ##### Re: !Num (Number Factorial)
« Reply #17 on: July 23, 2021, 07:15:01 pm »
NB: There are better algorithms to calculate the binomial coefficient.

And there are more appropriate computational frameworks than a strictly-procedural language such as Pascal. I'm moderately confident that even late-60s APL could handle something like 50! / 49! because it delayed the actual evaluation until as late as possible.

(Strictly, that would be written 49! ÷ 50! since evaluation was right-to-left.)

MarkMLl
Turbo Pascal v1 on CCP/M-86, multitasking with LAN and graphics in 128Kb.
Pet hate: people who boast about the size and sophistication of their computer.
GitHub repositories: https://github.com/MarkMLl?tab=repositories

#### BobDog

• Full Member
•   • Posts: 141 ##### Re: !Num (Number Factorial)
« Reply #18 on: July 26, 2021, 10:47:03 pm »

Without an external library, here is factorial of bigger numbers:
Code: Pascal  [Select][+][-]
1.    program fac;
2.      uses
3. SysUtils,DateUtils;  { only for the timer }
4.
5.
6.    function factorial(num:longint):ansistring ;
7.    type
8.      AT = array[0..99] of longint;
9.      var
10.      _mod,_div:at;
11.      fact,a,b,c:ansistring;
12.      pa,pb,pc:pchar;
13.      n,carry,ai:smallint;
14.      la,lb,i,j,z:longint;
15.
16.       begin //create lookup  tables
17.      for z:=0 to 99 do
18.      begin
19.      _mod[z]:= (z mod 10) +48;
20.      _div[z]:=  z div 10;
21.       end;  //created lookup tables
22.
23.        fact:='1';
24.       for z:=1 to num do
25.          begin
26.        a:=fact;Str(z,b);la:=Length(a);lb:=length(b);
27.        Setlength(c,la+lb);
28.        FillChar(c,la+lb,#48);
29.         pa:=@a; //set pointers
30.         pb:=@b;
31.         pc:=@c;
32.       for i:=la-1 downto 0 do
33.       begin
34.          carry:=0;ai:=ord(pa[i])-48 ;
35.       for j:= lb-1 downto 0 do
36.       begin
37.         n :=ai*(ord(pb[j])-48)+(ord(pc[i+j+1])-48)+carry;
38.         carry :=_Div[n];ord(pc[i+j+1]):=_Mod[n];
39.       end;
40.        ord(pc[i]):=ord(pc[i])+carry ;
41.       end;
42.       fact:=c;
43.       if c='0' then fact:=copy(c,2,length(c)-1) ;
44.       end;
45.        exit(fact);
46.       end;
47.
48.  {===========  start ===========}
49.       var
50.       e:ansistring;
51.     num:longint;
52.   D1,D2: TDateTime;
53.
54.        begin
55.        num:= 5000;
56.        writeln('factotial ',num,'  =  ');
57.        D1:=now;
58.        e:=  factorial(num);
59.        D2:=now;
60.        writeln(e);
61.        writeln( MilliSecondsBetween(D1, D2), ' milliseconds');