[
掲示板に戻る
]
記事No.64652に関するスレッドです
★
(No Subject)
/ たまご
引用
radの計算が計算機を使うと合いません。
計算機でのradの計算方法が知りたいです。
No.64652 - 2020/04/26(Sun) 16:58:51
☆
Re:
/ 関数電卓
引用
↓の展開式で計算しています。
No.64653 - 2020/04/26(Sun) 18:35:50
☆
Re:
/ 関数電卓
引用
x=-0.3 としてエクセルで計算すると
No.64654 - 2020/04/26(Sun) 18:50:02
☆
Re:
/ らすかる
引用
arcsinの展開式は扱いにくそうですが、実際に使われているのでしょうか?
私が以前電卓プログラムを作った時は、cosxを求めてarctanで計算しました。
No.64658 - 2020/04/26(Sun) 21:01:58
☆
Re:
/ たまご
引用
丁寧なお返事ありがとうございます。
No.64661 - 2020/04/26(Sun) 21:49:17
☆
Re:
/ 関数電卓
引用
> 実際に使われているのでしょうか?
いろいろ検索してみましたが,エクセルとか win 添付の電卓でどのような内部ルーチンを用いているかは,知ることが出来ませんでした。未確認での書き込み,失礼しました。
> cosxを求めてarctanで計算しました。
よく知られた方法だと思います。
arcsin(x) は |x|≦1 で収束が速く項数も少なくてすむため (求める精度にもよりますが),上の展開によるルーチンを作っても良いと思います。
No.64667 - 2020/04/26(Sun) 23:14:08
☆
Re:
/ らすかる
引用
> arcsin(x) は |x|≦1 で収束が速く項数も少なくてすむため (求める精度にもよりますが),
> 上の展開によるルーチンを作っても良いと思います。
「|x|≦1 で収束が速く」は言い過ぎでしょう。
例えば上の展開式でx=0.99とすると100項計算しても3〜4桁の精度しかありません。
xが1に近い場合は何かしら工夫が必要ですね。
まあ、その「何かしらの工夫」をしたとして、必要な精度が少ない項数の計算で
求まる程度であれば、専用のルーチンを用意しても良いと思います。
以下、多倍長の電卓を作った時の経験談です。
よくある展開式の形を整理すると、以下のものは形がそっくりで
共通ルーチンで処理できます。
(1) 階乗型・奇関数・符号一定
x + x^3/3! + x^5/5! + x^7/7! + … = sinhx = (e^x - e^-x)/2
(2) 階乗型・奇関数・符号交互
x - x^3/3! + x^5/5! - x^7/7! + … = sinx
(3) 階乗型・偶関数・符号一定
1 + x^2/2! + x^4/4! + x^6/6! + … = coshx = (e^x + e^-x)/2
(4) 階乗型・偶関数・符号交互
1 - x^2/2! + x^4/4! - x^6/6! + … = cosx
(5) 非階乗型・奇関数・符号一定
x + x^3/3 + x^5/5 + x^7/7 + … = atanhx = log((1+x)/(1-x))/2
(6) 非階乗型・奇関数・符号交互
x - x^3/3 + x^5/5 - x^7/7 + … = atanx
(7) 非階乗型・偶関数・符号一定
1 + x^2/2 + x^4/4 + x^6/6 + … = 1 - log(1-x^2)/2
(8) 非階乗型・偶関数・符号交互
1 - x^2/2 + x^4/4 - x^6/6 + … = 1 - log(1+x^2)/2
このうち(7)(8)は特殊なので使っていません。(3)も使っていません。
上記の他に「平方根」は必要ですが、これはニュートン法など使えますので
多倍長でも収束が速いです。
上記のルーチンを作っておくと、初等関数が以下のように計算できます。
sinx,cosx
(2)と(4)を使う(sinxで(2)、cosxで(4)を使うとは限らない)
※級数計算に使う値は0〜π/4の範囲になるように工夫する
tanx
値により(2)か(4)を使ってsinxかcosxを求め、(sinx)^2+(cosx)^2=1により
他方を求めてsinx/cosxを計算する
arcsinx
|cosy|=√(1-x^2)で|cosy|を求めて(6)を使って求める(符号に要注意)
arccosx
|siny|=√(1-x^2)で|siny|を求めて(6)を使って求める(符号に要注意)
arctanx
(6)を使う
※級数計算に使う値は0〜tan(π/16)≒0.2の範囲になるように工夫する
sinhx
e^xを求めて(e^x-e^(-x))/2を計算する(e^xの求め方は後述)
※xが大きい場合を考えると、そのまま(1)を使うことはできない
coshx
e^xを求めて(e^x+e^(-x))/2を計算する
※xが大きい場合を考えると、そのまま(3)を使うことはできない
tanhx
e^(2x)を求めて(e^(2x)-1)/(e^(2x)+1)を計算する
arcsinhx
log(x+√(x^2+1))により計算(x<0のとき誤差に注意する)
arccoshx
log(x+√(x^2-1))により計算
arctanhx
log((1+x)/(1-x))/2により計算
※xが大きい場合を考えると、そのまま(5)を使うことはできない
e^x
e^x=e^y×2^n(|y|≦log2/2,nは整数)により指数を小さくして
(1)でsinhyを求め、coshy=√((sinhy)^2+1)でcoshyを求め、
e^y=sinhy+coshyで求める
※sinhxの式はe^xの式より半分の項で求まるためこの方が速い
※しかもe^xの専用処理を作る必要がない
logx
logx=logy+nlog2(1/√2≦y≦√2,nは整数)により真数を小さくし、
z=(y-1)/(y+1)として(5)を使って計算する
|z|≦3-2√2≒0.17なのでこうすると収束が速い
※log2の定数だけ別に計算が必要
以上のように、「上記の共通ルーチン」と「平方根計算」だけあれば
初等関数が全て片付きますので、この状況ではarcsinxの専用ルーチンを
作ろうとは思わないですね。
# 上記はまだ高速化の余地がありますが、上記の処理で目的には十分でした。
# 「sin1を1億桁求めたい」のような場合は上記では不十分です。
No.64682 - 2020/04/27(Mon) 16:17:13