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 ...
これはグレゴリー・ライプニッツ級数に等しいため、piに等しく、約3.1415926535 8979323846 2643383279 5028841971 69399373510です。
Atanを使用してpiを見つける別の方法は次のとおりです。
pi = 16 * atan(1/5)-4 * atan(1/239)ですが、もっと複雑だと思います。
これがお役に立てば幸いです!
(正直に言うと、グレゴリー・ライプニッツシリーズはグレゴリー・ライプニッツシリーズに基づく4 * atan(1)ではなく、atanに基づいていたと思います。
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)
コメントを私にロードしないでください-私はまだ十代前です。
これは、pi
を任意の精度で計算する正確な方法だからです。関数を実行し続けるだけで精度を高め、任意の時点で停止して近似値を得ることができます。
対照的に、pi
を定数として指定すると、元々与えられた精度とまったく同じ精度が得られますが、これは高度な科学的または数学的なアプリケーションには適していません(Fortranがよく使用されます)。
この質問には、目に見える以上のものがあります。なぜ4 arctan(1)
?なぜ3 arccos(1/2)
などの他の表現がないのですか?
これは、除外によって答えを見つけようとします。
数学的イントロ:arccos、arcsinなどの逆三角関数を使用する場合)およびarctan、さまざまな方法で簡単にπを計算できます。
_π = 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:有限2進浮動小数点表現はall実数。そのような数の例は、1/3, 0.97, π, sqrt(2), ...
です。このために、逆三角関数の引数を数値で表現できない場合のπの数学計算をexcludeする必要があります。これにより、引数_-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.bとして表されますnbn-1... b x 2m。逆三角関数がその引数に最適な数値バイナリ近似を考え出した場合、乗算によって精度を失いたくありません。このため、2の累乗で乗算する必要があります。
_π = 4 arctan(1) = 2 arcsin(1)
= 2 arccos(0)
= -4 arctan(-1) = arccos(-1) = -2 arcsin(-1)
_
note:これは 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)
_
他のすべての上。
注:これはあいまいな引数です。私はこれについてより良い意見を持つ人々がいると確信しています。
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
_
答えは Fortran標準 にあります。標準neverは、あらゆる種類のREAL
が IEEE-754浮動小数点数 を表す必要があると述べています。 REAL
の表現はプロセッサに依存します。これは、selected_real_kind(33, 4931)
を照会して binary128浮動小数点数 を取得することを期待できることを意味しますが、はるかに高い浮動小数点を表すkind
が返される場合があります正確さ。たぶん、100桁でしょう。この場合、上記の数字の列は短くなります! this を使用することはできませんか?そのファイルでも短すぎる可能性があります!
興味深い事実: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
_