8.1.27 Escreva um subprograma de função F A C T(N) (variável independente de ponto fixo) para calcular N!. Inclua provisão para rejeição e mensagem de erro adequada se N for negativo.
Nota: Para N inteiro pequeno, multiplicação direta é mais simples. Para N grande, a Equação (8.55), a série de Stirling, seria adequada.

Passo 1

O enunciado pede um subprograma de função FACT(N) para calcular N! com duas provisões principais: ( 1) rejeitar valores de N negativos exibindo mensagem de erro, e ( 2) usar multiplicação direta quando N é pequeno e, para N grande, usar a série de Stirling (Equação 8.55) para aproximar ln(N!) e em seguida exponenciar.

Passo 2

Validar a entrada: testar se N<0. Se for verdade, imprimir mensagem de erro e terminar a função retornando valor simbólico (por exemplo -1) para indicar falha.

Passo 3

Definir um limite N0 até o qual se calcula o fatorial exato por multiplicação direta. Por exemplo, escolher N0=20 (pois 20! cabe em precisão dupla). Se 0<= N<= N0, fazer um laço de 1 a N multiplicando sucessivamente para obter N!.

Passo 4

Para N>N0, usar a aproximação de Stirling. Primeiro calcular
ln(N!) approx Nln N - N + tfrac12ln(2pi N) + 112N - 1360N^3
Essa expressão inclui termos de ordem O(N^-1) e O(N^-3) para melhorar a precisão.

Passo 5

Obter a aproximação de N! exponenciando o resultado do passo anterior:
N! approx expl(ln(N!)r)

Passo 6

Retornar o valor calculado (direto ou aproximado).

Resposta

FUNCTION FACT(N)
  ! Subprograma para calcular N! (N inteiro >\(=0\))
  REAL*\(8\) FACT
  INTEGER N, I
  REAL*\(8\) F, lnF, x, PI
  PARAMETER (PI\(=3.141592653589793\)D\(0\))
  INTEGER, PARAMETER :: N\(0=20\)

  IF (N .LT. \(0\)) THEN
    PRINT *, 'Erro: N deve ser inteiro >\(=0\).'
    FACT \(=\) -\(1.0\)D\(0\)
    RETURN
  END IF

  IF (N .LE. N\(0\)) THEN
    F \(=1.0\)D\(0\)
    DO I \(=2\), N
      F \(=\) F * I
    END DO
    FACT \(=\) F
  ELSE
    x \(=\) DBLE(N)
    lnF \(=\) x*LOG(x) - x \(+0.5\)D\(0\)*LOG(\(2.0\)D\(0\)*PI*x) \(+1.0\)D\(0\)/(\(12.0\)D\(0\)*x) - \(1.0\)D\(0\)/(\(360.0\)D\(0\)*x**\(3\))
    FACT \(=\) EXP(lnF)
  END IF
END FUNCTION FACT

Exercícios de Livros Relacionados