Desenvolva um código em Fortran que seja capaz de realizar
a soma do número 1 por 100.000 vezes, usando precisão simples.
a soma do número 1 por 100.000 vezes, usando precisão simples.
Passo 1
O enunciado pede um programa em Fortran que realize a soma do número
por
vezes usando precisão simples.
Informações dadas e o que é solicitado:
Informações dadas e o que é solicitado:
- Somar a quantidade
repetidamente. - O número de repetições é
. - Deve ser usada precisão simples (single precision) para as variáveis reais.
- Entregar o código em Fortran que faça isso (deve poder ser compilado e executado).
Passo 2
Estratégia/algoritmo simples (em palavras, sem código ainda):
- Declarar uma variável
em precisão simples para acumular a soma. - Declarar uma variável
em precisão simples contendo o valor . - Declarar um contador inteiro
e um inteiro com . - Inicializar
. - Fazer um laço que execute de
até e em cada iteração executar . - Ao final, imprimir
.
Este é o método mais direto e robusto para o pedido. Não exige estruturas complexas e é o que normalmente se pede numa prova básica de programação numérica.
Passo 3
Conceitos importantes sobre precisão simples (explicação didática e curta):
- Computadores representam números reais em ponto flutuante seguindo um padrão (normalmente IEEE-754). Um número em ponto flutuante tem sinal, expoente e mantissa (às vezes chamada de fração).
- Na precisão simples típica (IEEE-754 single), a mantissa tem
bits de precisão (incluindo o bit implícito). Isso significa que todos os inteiros até são representados exatamente (sem arredondamento). - A “máquina epsilon” para single é aproximadamente
. Esse valor dá uma ideia do menor incremento relativo distinguível perto de . - Consequência prática para este exercício: somar
repetidamente vezes em precisão simples deve resultar exatamente em , pois e os inteiros intermediários permanecem exatos. Portanto, o método direto não perde exatidão aqui.
Passo 4
Boas práticas e escolhas em Fortran que vou usar (explicando por que):
- Evitar o uso de
REAL*4ouREAL(KIND=4)escrito literalmente pode ser menos portátil. Uma opção mais portátil é usarselected_real_kind(p=6), que pede uma precisão decimal mínima (aproximadamente 6 dígitos decimais, apropriada para single). Vou declarar um parâmetrospcomselected_real_kind(p=6)e usarREAL(kind=sp). - Sempre usar
implicit nonepara evitar erros de nomes de variáveis. - Inicializar explicitamente
sumcom0.0em escala do tipo single usandoreal(0.0, kind=sp)ou literal com especificação de kind. - Usar um laço
dosimples. - Imprimir o resultado com um formato legível.
Passo 5
Explicação linha a linha do que o código fará (sem mostrar o código aqui):
- Programa começa e força declaração explícita (
implicit none). - Define
sp = selected_real_kind(p=6)para representar o “kind” de precisão simples. - Declara
integer :: i, nereal(kind=sp) :: one, sum. - Atribui
n = 100000,one = real(1.0, kind=sp)esum = real(0.0, kind=sp). - Executa
do i = 1, ncomsum = sum + one. - Fecha o laço e imprime
nesum(por exemplo com formatoF12.6para ver casas decimais). - Encerra o programa.
Passo 6
Como compilar e executar (exemplo com gfortran):
- Salve o código em um arquivo, por exemplo
sum_one.f90. - Compile com:
gfortran -std=f2008 -O2 -o sum_one sum_one.f90 - Execute com:
./sum_one
Saída esperada: o programa imprimirá o valor de, que deverá ser (ou 100000.000000dependendo do formato de impressão), porque, como explicado, inteiros atécabem exatamente em single.
Passo 7
Observações finais e variações:
- Se o número de somas
fosse muito maior que , a soma por adição sequencial em single poderia começar a perder unidades (ou seja, sum + 1pode não aumentar quandosumficou grande o suficiente). Nesse caso, soluções como usar precisão dupla ou algoritmos de soma compensada (p.ex. Kahan) seriam recomendadas. - Para este exercício específico (
), a solução direta é suficiente e exata em single precision. - Se for exigido explicitamente usar uma notação literal com kind, pode-se optar por
one = 1.0_sp— isso requer quespseja um parâmetro conhecido no momento da escrita do literal.
Resposta
program sum_one_single
implicit none
integer, parameter :: sp = selected_real_kind(p=6)
integer :: i, n
real(kind=sp) :: one, sum
n = 100000
one = real(1.0, kind=sp)
sum = real(0.0, kind=sp)
do i = 1, n
sum = sum + one
end do
write(*,'(A,I0)') 'n = ', n
write(*,'(A,F12.6)') 'sum (single precision) = ', sum
end program sum_one_single