poner parameter como advance fortran fortran77 pi

como - parameter fortran



Por qué definir PI=4*ATAN(1.d0) (6)

Creo que es porque esta es la serie más corta en pi. Eso también significa que es el MÁS EXACTO.

La serie Gregory-Leibniz (4/1 - 4/3 + 4/5 - 4/7 ...) es igual a pi.

atan (x) = x ^ 1/1 - x ^ 3/3 + x ^ 5/5 - x ^ 7/7 ...

Entonces, atan (1) = 1/1 - 1/3 + 1/5 - 1/7 + 1/9 ... 4 * atan (1) = 4/1 - 4/3 + 4/5 - 4 / 7 + 4/9 ...

Eso equivale a la serie Gregory-Leibniz, y por lo tanto es igual a pi, aproximadamente 3.1415926535 8979323846 2643383279 5028841971 69399373510.

Otra forma de usar atan y encontrar pi es:

pi = 16 * atan (1/5) - 4 * atan (1/239), pero creo que eso es más complicado.

¡Espero que esto ayude!

(Para ser honesto, creo que la serie de Gregory-Leibniz se basó en atan, no en 4 * atan (1) basada en la serie de Gregory-Leibniz. En otras palabras, la prueba REAL es:

sin ^ 2 x + cos ^ 2 x = 1 [Teorema] Si x = pi / 4 radianes, sin ^ 2 x = cos ^ 2 x, o sin ^ 2 x = cos ^ 2 x = 1/2.

Entonces, sen x = cos x = 1 / (raíz 2). tan x (sin x / cos x) = 1, atan x (1 / tan x) = 1.

Entonces, si atan (x) = 1, x = pi / 4 y atan (1) = pi / 4. Finalmente, 4 * atan (1) = pi)

Por favor, no me cargue con comentarios, todavía soy un preadolescente.

¿Cuál es la motivación para definir PI como

PI=4.D0*DATAN(1.D0)

dentro del código Fortran 77? Entiendo cómo funciona, pero, ¿cuál es el razonamiento?


Es porque esta es una forma exacta de calcular pi con precisión arbitraria. Simplemente puede continuar ejecutando la función para obtener mayor precisión y detenerse en cualquier punto para tener una aproximación.

Por el contrario, especificar pi como constante le proporciona exactamente tanta precisión como se le dio originalmente, lo que puede no ser apropiado para aplicaciones altamente científicas o matemáticas (como se usa con frecuencia Fortran).


Eso suena bastante como una solución para un error de compilación. O podría ser que este programa en particular dependa de que la identidad sea exacta, por lo que el programador lo garantizó.


Este estilo garantiza que la precisión máxima disponible en CUALQUIER arquitectura se utilice al asignar un valor a PI.


Hay más en esta pregunta que se ve a simple vista. ¿Por qué 4 arctan(1) ? ¿Por qué no otra representación como 3 arccos(1/2) ?

Esto intentará encontrar una respuesta por exclusión.

Introducción matemática: cuando se utilizan funciones trigonométricas inversas como arccos, arcsin y arctan , se puede calcular fácilmente π de varias maneras:

π = 4 arctan(1) = arccos(-1) = 2 arcsin(1) = 3 arccos(1/2) = 6 arcsin(1/2) = 3 arcsin(sqrt(3)/2) = 4 arcsin(sqrt(2)/2) = ...

Existen muchas otras expresiones algebraicas exactas para los valores trigonométricos que podrían usarse aquí.

argumento de punto flotante 1: se entiende bien que una representación de coma flotante binaria finita no puede representar todos los números reales. Algunos ejemplos de tales números son 1/3, 0.97, π, sqrt(2), ... Para este fin, deberíamos excluir cualquier cálculo matemático de π donde el argumento para las funciones trigonométricas inversas no pueda representarse numéricamente. Esto nos deja los argumentos -1,-1/2,0,1/2 y 1 .

π = 4 arctan(1) = 2 arcsin(1) = 3 arccos(1/2) = 6 arcsin(1/2) = 2 arccos(0) = 3/2 arccos(-1/2) = -6 arcsin(-1/2) = -4 arctan(-1) = arccos(-1) = -2 arcsin(-1)

argumento de coma flotante 2: en la representación binaria, un número se representa como 0.b n b n-1 ... b 0 x 2 m . Si la función trigonométrica inversa obtuvo la mejor aproximación binaria numérica para su argumento, no queremos perder precisión por multiplicación. Para este fin, solo deberíamos multiplicarnos con potencias de 2.

π = 4 arctan(1) = 2 arcsin(1) = 2 arccos(0) = -4 arctan(-1) = arccos(-1) = -2 arcsin(-1)

nota: esto es visible en la representación binary64 de IEEE-754 (forma más común de DOUBLE PRECISION o kind=REAL64 ). Ahí tenemos

write(*,''(F26.20)'') 4.0d0*atan(1.0d0) -> " 3.14159265358979311600" write(*,''(F26.20)'') 3.0d0*acos(0.5d0) -> " 3.14159265358979356009"

Esta diferencia no está en IEEE-754 binary32 (la forma más común de REAL o kind=REAL32 ) y IEEE-754 binary128 (forma más común de kind=REAL128 )

argumento de implementación difusa: a partir de este punto, todo depende un poco de la implementación de las funciones trigonométricas inversas. A veces arccos y arcsin se derivan de atan2 y atan2 como

ACOS(x) = ATAN2(SQRT(1.-x*x),1) ASIN(x) = ATAN2(1,SQRT(1.-x*x))

Además, atan2 es parte del conjunto de instrucciones x86 como FPATAN mientras que los otros no lo son. Para este fin, yo discutiría el uso de:

π = 4 arctan(1)

sobre todos los demás.

Nota: este es un argumento difuso. Estoy seguro de que hay personas con mejores opiniones sobre esto.

El argumento de Fortran: ¿por qué deberíamos aproximarnos a π como:

integer, parameter :: sp = selected_real_kind(6, 37) integer, parameter :: dp = selected_real_kind(15, 307) integer, parameter :: qp = selected_real_kind(33, 4931) real(kind=sp), parameter :: pi_sp = 4.0_sp*atan2(1.0_sp,1.0_sp) real(kind=dp), parameter :: pi_dp = 4.0_dp*atan2(1.0_dp,1.0_dp) real(kind=qp), parameter :: pi_qp = 4.0_qp*atan2(1.0_qp,1.0_qp)

y no :

real(kind=sp), parameter :: pi_sp = 3.14159265358979323846264338327950288_sp real(kind=dp), parameter :: pi_dp = 3.14159265358979323846264338327950288_dp real(kind=qp), parameter :: pi_qp = 3.14159265358979323846264338327950288_qp

La respuesta está en el estándar Fortran . La norma nunca establece que un REAL de ningún tipo debe representar un número de coma flotante IEEE-754 . La representación de REAL depende del procesador. Esto implica que podría consultar selected_real_kind(33, 4931) y esperar obtener un número de punto flotante binario128 , pero podría obtener un kind devuelto que representa un punto flotante con una precisión mucho mayor. Tal vez 100 dígitos, quién sabe. ¡En este caso, mi cadena de números anterior es muy corta! No se puede usar this solo para estar seguro? ¡Quizás sea demasiado corto!

hecho interesante: sin(pi) is never zero

write(*,''(F17.11)'') sin(pi_sp) => " -0.00000008742" write(*,''(F26.20)'') sin(pi_dp) => " 0.00000000000000012246" write(*,''(F44.38)'') sin(pi_qp) => " 0.00000000000000000000000000000000008672"

que se entiende como:

pi = 4 ATAN2(1,1) = π + δ SIN(pi) = SIN(pi - π) = SIN(δ) ≈ δ

program print_pi ! use iso_fortran_env, sp=>real32, dp=>real64, qp=>real128 integer, parameter :: sp = selected_real_kind(6, 37) integer, parameter :: dp = selected_real_kind(15, 307) integer, parameter :: qp = selected_real_kind(33, 4931) real(kind=sp), parameter :: pi_sp = 3.14159265358979323846264338327950288_sp real(kind=dp), parameter :: pi_dp = 3.14159265358979323846264338327950288_dp real(kind=qp), parameter :: pi_qp = 3.14159265358979323846264338327950288_qp write(*,''("SP "A17)'') "3.14159265358..." write(*,''(F17.11)'') pi_sp write(*,''(F17.11)'') acos(-1.0_sp) write(*,''(F17.11)'') 2.0_sp*asin( 1.0_sp) write(*,''(F17.11)'') 4.0_sp*atan2(1.0_sp,1.0_sp) write(*,''(F17.11)'') 3.0_sp*acos(0.5_sp) write(*,''(F17.11)'') 6.0_sp*asin(0.5_sp) write(*,''("DP "A26)'') "3.14159265358979323846..." write(*,''(F26.20)'') pi_dp write(*,''(F26.20)'') acos(-1.0_dp) write(*,''(F26.20)'') 2.0_dp*asin( 1.0_dp) write(*,''(F26.20)'') 4.0_dp*atan2(1.0_dp,1.0_dp) write(*,''(F26.20)'') 3.0_dp*acos(0.5_dp) write(*,''(F26.20)'') 6.0_dp*asin(0.5_dp) write(*,''("QP "A44)'') "3.14159265358979323846264338327950288419..." write(*,''(F44.38)'') pi_qp write(*,''(F44.38)'') acos(-1.0_qp) write(*,''(F44.38)'') 2.0_qp*asin( 1.0_qp) write(*,''(F44.38)'') 4.0_qp*atan2(1.0_qp,1.0_qp) write(*,''(F44.38)'') 3.0_qp*acos(0.5_qp) write(*,''(F44.38)'') 6.0_qp*asin(0.5_qp) write(*,''(F17.11)'') sin(pi_sp) write(*,''(F26.20)'') sin(pi_dp) write(*,''(F44.38)'') sin(pi_qp) end program print_pi


Porque Fortran no tiene una constante incorporada para PI . Pero en lugar de ingresar el número manualmente y cometer un error potencial o no obtener la máxima precisión posible en la implementación dada, dejar que la biblioteca calcule el resultado garantiza que ninguno de esos inconvenientes ocurra.

Estos son equivalentes y a veces los verás también:

PI=DACOS(-1.D0) PI=2.D0*DASIN(1.D0)