Recent

Author Topic: !Num (Number Factorial)  (Read 5380 times)

winni

  • Hero Member
  • *****
  • Posts: 2664
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

  • Sr. Member
  • ****
  • Posts: 357
  • Whasup!?
    • KaiBurghardt.de
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: 3066
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: 129
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[1],la+lb,#48);
  29.         pa:=@a[1]; //set pointers
  30.         pb:=@b[1];
  31.         pc:=@c[1];
  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[1]='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');
  62.        writeln('Press return to end . . .');
  63.        readln;
  64.        end.
  65.  
  66.  

 

TinyPortal © 2005-2018