Почему определить PI = 4 * ATAN(1.d0)



какова мотивация для определения PI как



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


в коде Fortran 77? Я понимаю, как это работает, но, что такое рассуждение?

550   6  

6 ответов:

этот стиль гарантирует, что максимальная точность, доступная на любой архитектуре, используется при присвоении значения PI.

потому что Fortran не имеет встроенной константы для PI. Но вместо того, чтобы вводить число вручную и потенциально делать ошибку или не получать максимально возможную точность в данной реализации, позволяя библиотеке вычислить результат для вас, гарантирует, что ни один из этих недостатков не произойдет.

они эквивалентны, и вы иногда будете видеть их тоже:

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

Я считаю, что это потому, что это самая короткая серия на pi. Это также означает, что он самый точный.

Грегори-Лейбница серии (4/1 - 4/3 + 4/5 - 4/7...) равно Пи.

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

Так, Атан(1) = 1/1 - 1/3 + 1/5 - 1/7 + 1/9... 4 * Атан(1) = 4/1 - 4/3 + 4/5 - 4/7 + 4/9...

что равно ряду Грегори-Лейбница, и поэтому равно pi, приблизительно 3.1415926535 8979323846 2643383279 5028841971 69399373510.

другой способ использовать atan и найти pi:

Пи = 16*Атан(1/5) - 4*Атан(1/239), но я думаю, что это сложнее.

надеюсь, это поможет!

(честно говоря, я думаю, что серия Григория-Лейбница была основана на atan, а не 4*atan(1), основанный на серии Григория-Лейбница. Другими словами, реальное доказательство:

sin^2 x + cos^2 x = 1 [Теорема] Если x = pi / 4 Радиана, sin^2 x = cos^2 x, или sin^2 x = cos^2 x = 1/2.

тогда sin x = cos x = 1 / (корень 2). tan x (sin x / cos x) = 1, atan x (1 / tan x) = 1.

Итак, если atan(x) = 1, x = pi/4 и atan (1) = pi/4. Наконец, 4 * atan (1) = pi.)

пожалуйста, не загружайте меня комментариями-я все еще подросток.

Это потому, что это точный способ вычисления pi с произвольной точностью. Вы можете просто продолжить выполнение функции, чтобы получить все большую и большую точность и остановиться в любой точке, чтобы иметь приближение.

напротив, задание pi как константа предоставляет вам ровно столько точности, сколько было первоначально дано, что может не подходить для высоконаучных или математических приложений (как часто используется Fortran).

в этом вопросе есть больше, чем кажется на первый взгляд. Почему 4 arctan(1)? Почему бы не любое другое представление, такое как 3 arccos(1/2)?

это будет пытаться найти ответ путем исключения.

математические интро: при использовании обратные тригонометрические функции например arccos, arcsin и равенства arctg, можно легко вычислить π различными способами:

π = 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) = ...

существует много других точное алгебраические выражения для тригонометрических значений это может быть использовано здесь.

аргумент с плавающей запятой 1: хорошо понятно, что а конечное двоичное представление с плавающей точкой не может представлять все реальные цифры. Некоторые примеры таких чисел 1/3, 0.97, π, sqrt(2), .... С этой целью мы должны исключить любое математическое вычисление π, где аргумент обратных тригонометрических функций не может быть представлен численно. Это оставляет нам аргументы -1,-1/2,0,1/2 и 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)

аргумент с плавающей запятой 2: в двоичном представлении число представляется как 0.bnbn-1...b0 x 2m. Если обратная тригонометрическая функция придумала лучшее числовое двоичное приближение для своего аргумента, мы не хотим терять точность умножения. С этой целью мы должны только умножьте со степенями 2.

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

Примечание: это видно в IEEE-754 binary64 представление (наиболее распространенная форма DOUBLE PRECISION или kind=REAL64). Там у нас есть

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

эта разница не существует в IEEE-754 binary32 (наиболее распространенная форма REAL или kind=REAL32) и IEEE-754 binary128 (наиболее распространенная форма kind=REAL128)

нечеткой реализации аргумент: С этого момента все немного зависит от реализации обратных тригонометрических функций. Иногда arccos и arcsin полученные от atan2 и atan2 как

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

или, более конкретно, с числовой точки зрения:

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

кроме того, atan2 является частью x86 набор инструкций как FPATAN в то время как другие нет. С этой целью я бы поспорил об использовании:

π = 4 arctan(1)

за все остальные.

Примечание: это нечеткий аргумент. Я уверен, что есть люди с лучшим мнением об этом.

аргумент Фортран: почему мы должны приблизительные π как :

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)

и

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

ответ лежит в Fortran standard. Стандартный никогда утверждает, что a REAL любой вид должен представлять собой IEEE-754 с плавающей точкой номер. Представление REAL зависит от процессора. Это означает, что я мог бы спросить selected_real_kind(33, 4931) и ожидать, чтобы получить binary128 число с плавающей запятой, но я мог бы получить kind возвращается, что представляет собой плавающую точку с гораздо более высокой точностью. Может быть, 100 цифр, кто знает. В этом случае моя вышеприведенная строка чисел должна быть короткой! Нельзя использовать этой просто чтобы быть уверенным? Даже этот файл может быть слишком коротко!

интересный факт : 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"

что понимается как:

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

Это звучит очень похоже на обходной путь для ошибки компилятора. Или может быть, что эта конкретная программа зависит от того, что идентичность является точной, и поэтому программист сделал это гарантированным.

Comments

    Ничего не найдено.