unit factorialF;

{$mode objfpc}{$H+}

interface

uses
  Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls,
  Spin;

type

  { TForm1 }

  TForm1 = class(TForm)
    btnFactoriales: TButton;
    btnFactorialesExc: TButton;
    mMostrar: TMemo;
    seNumero: TSpinEdit;
    procedure btnFactorialesClick(Sender: TObject);
    procedure btnFactorialesExcClick(Sender: TObject);
    private
      function Factorial64(aByte: byte): int64;
      function Factorial64Exc(aByte: byte): int64;
   end;

var
  Form1: TForm1;

implementation

{$R *.lfm}

{ TForm1 }

procedure TForm1.btnFactorialesClick(Sender: TObject);
  var i: integer;
begin

  mMostrar.Lines.Clear;
  for i := 1 to seNumero.Value do
      mMostrar.Lines.Add(Format('%d! es %s',[i, FormatFloat(',#', Factorial64(i))]));
end;

procedure TForm1.btnFactorialesExcClick(Sender: TObject);
  var i: integer;
begin

  mMostrar.Lines.Clear;
  for i := 1 to seNumero.Value do
      mMostrar.Lines.Add(Format('%d! es %s',[i, FormatFloat(',#', Factorial64Exc(i))]));
end;

function TForm1.Factorial64(aByte: byte): int64;
begin
  case aByte of
    0, 1: Result:= 1;
  else Result:= aByte * Factorial64(aByte - 1);
  end;

end;

function TForm1.Factorial64Exc(aByte: byte): int64;
begin
  Result:= -1;
  case aByte of
    0, 1: Result:= 1;
  else
    try
    Result:= aByte * Factorial64Exc(aByte - 1);
    except on e:EIntOverflow do
    MessageDlg('Problema',
    Format('"%s"%s El número %d ha causado en la función Factorial64Exc'+
    ' el desbordamiento señalado ',
    [e.Message, LineEnding, aByte]), mtWarning, [mbClose],0);
    end;
  end;
end;
end.

