Programing

PI = 4 * ATAN (1.d0)을 정의하는 이유

crosscheck 2021. 1. 7. 19:42
반응형

PI = 4 * ATAN (1.d0)을 정의하는 이유


PI를 다음과 같이 정의하는 동기는 무엇입니까?

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

Fortran 77 코드 내에서? 어떻게 작동하는지 이해하지만 그 이유는 무엇입니까?


이 스타일은 PI에 값을 할당 할 때 모든 아키텍처에서 사용할 수있는 최대 정밀도가 사용되도록합니다.


Fortran에는에 대한 내장 상수가 없기 때문입니다 PI. 그러나 숫자를 수동으로 입력하고 잠재적으로 실수를하거나 주어진 구현에서 가능한 최대 정밀도를 얻지 못하는 대신 라이브러리가 결과를 계산하도록하여 이러한 단점이 발생하지 않도록 보장합니다.

이것들은 동등하며 때때로 그것들도 볼 수 있습니다 :

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

파이에서 가장 짧은 시리즈이기 때문이라고 생각합니다. 그것은 또한 가장 정확하다는 것을 의미합니다.

Gregory-Leibniz 시리즈 (4/1-4/3 + 4/5-4/7 ...)는 pi와 같습니다.

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

따라서 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 ...

이는 Gregory-Leibniz 시리즈와 같으므로 pi와 같습니다 (약 3.1415926535 8979323846 2643383279 5028841971 69399373510).

atan을 사용하고 pi를 찾는 또 다른 방법은 다음과 같습니다.

pi = 16 * atan (1/5)-4 * atan (1/239)이지만 더 복잡하다고 생각합니다.

이게 도움이 되길 바란다!

(솔직히 말하자면 Gregory-Leibniz 시리즈는 Gregory-Leibniz 시리즈에 기반한 4 * atan (1)이 아니라 atan에 기반한 것 같습니다. 즉, REAL 증명은 다음과 같습니다.

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 / (root 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.)

댓글을 달지 말아주세요. 저는 아직 10 대 초반입니다.


이것은 pi임의의 정밀도 로 계산하는 정확한 방법이기 때문 입니다. 더 크고 더 높은 정밀도를 얻기 위해 함수를 계속 실행하고 근사치를 얻기 위해 언제든지 중지 할 수 있습니다.

반대로 pi상수로 지정 하면 원래 제공된 것과 동일한 정밀도를 제공하므로 고도의 과학적 또는 수학적 응용 프로그램에는 적합하지 않을 수 있습니다 (Fortran이 자주 사용됨).


이 질문에는 눈에 보이는 것보다 더 많은 것이 있습니다. 4 arctan(1)? 와 같은 다른 표현은 왜 안 3 arccos(1/2)됩니까?

이것은 배제로 답을 찾으려고 할 것입니다.

수학적 소개 : arccos, arcsinarctan같은 역삼 각 함수를 사용할 때 다양한 방법으로 π를 쉽게 계산할 수 있습니다.

π = 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/21.

π = 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.b n b n-1 ... b 0 x 2 m로 표시 됩니다. 역삼 각 함수가 인수에 대해 가장 좋은 숫자 이진 근사값을 내놓았다면 곱셈으로 정밀도를 잃고 싶지 않습니다. 이를 위해 우리는 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)에는 없습니다.

퍼지 구현 인수 : 이 시점에서 모든 것은 역삼 각 함수의 구현에 약간 의존합니다. 때로는 arccosarcsin에서 파생 atan2atan2같은

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)))

또한 x86 명령어 세트의atan2 일부 이지만 나머지는 그렇지 않습니다. 이를 위해 나는 다음의 사용법을 주장합니다.FPATAN

π = 4 arctan(1)

다른 모든 것보다.

참고 : 이것은 모호한 인수입니다. 나는 이것에 대해 더 나은 의견을 가진 사람들이 있다고 확신합니다.

Fortran 주장 : 왜 우리 π는 다음과 같이 근사해야합니까?

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

The answer lays in the Fortran standard. The standard never states that a REAL of any kind should represent an IEEE-754 floating point number. The representation of REAL is processor dependent. This implies that I could inquire selected_real_kind(33, 4931) and expect to obtain a binary128 floating point number, but I might get a kind returned that represents a floating point with a much higher accuracy. Maybe 100 digits, who knows. In this case, my above string of numbers is to short! One cannot use this just to be sure? Even that file could be too short!

interesting fact : 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"

which is understood as:

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

That sounds an awful lot like a work-around for a compiler bug. Or it could be that this particular program depends on that identity being exact, and so the programmer made it guaranteed.

ReferenceURL : https://stackoverflow.com/questions/2157920/why-define-pi-4atan1-d0

반응형