C言語関係掲示板

過去ログ

No.1312 逆関数(arcsin)

[戻る] [ホームページ]
No.17607

逆関数(arcsin)
投稿者---k2(2004/10/28 20:22:09)


はじめまして、下手な文章ですがよろしくお願いします。
私は、今H8マイコンのプログラムをc言語で作っています。
arcsinの計算をさせたいのですが、ヘッダファイル(math.h)にasin関数が
定義されていないので、自分で関数を作る必要があるのですが、私の知識では
作れないので何か参考になること(簡単な数値計算で近似できるなど)、
参考になるようなページをご存知の方、
申し訳ないですが教えていただけないでしょうか?


No.17610

Re:逆関数(arcsin)
投稿者---かずま(2004/10/28 22:25:17)


> arcsinの計算をさせたいのですが、ヘッダファイル(math.h)にasin関数が
> 定義されていないので、自分で関数を作る必要があるのですが、私の知識では
> 作れないので何か参考になること(簡単な数値計算で近似できるなど)、

<math.h> があるということは、atan または atan2 があるでしょう。
double arcsin(double x)
{
    if (x < -1 || x > 1) return 0; /* exit(1); */
    return atan2(x, sqrt(1 - x*x));
}



No.17613

Re:逆関数(arcsin)
投稿者---k2(2004/10/28 22:53:11)


><math.h> があるということは、atan または atan2 があるでしょう。
レスありがとうございます。atan,atan2両方とも<math.h>になかったです・・

投稿後いろいろ調べて、arcsinをテーラー展開して近似することに
しました。


No.17617

Re:逆関数(arcsin)
投稿者---かずま(2004/10/29 11:55:18)


> 投稿後いろいろ調べて、arcsinをテーラー展開して近似することに
> しました。

どんなプログラムになりましたか?
arcsin(x) で x が 1 に近い値だと、なかなか収束しないので、ちょっと
工夫が必要だと思います。
#include <math.h>

#define PI       3.141592653589793238
#define SQRT_2   1.414213562373095048
#define EPSILON  1e-15

double arcsin(double x)
{
    double i, i2, s, t;  int sign = 0, large = 0;

    if (x < 0) sign = 1, x = -x;
    if (x > 1) return 0; /* error */
    if (x > SQRT_2 / 2) large = 1, x = sqrt(1 - x*x);
    s = t = x;
    for (i = 1; t > EPSILON; i++) {
        i2 = i * 2;
        t *= i2 * (i2 - 1) * x * x / (4 * i * i);
        s += t / (i2 + 1);
    }
    if (large) s = PI/2 - s;
    return sign ? -s : s;
}



No.17618

Re:逆関数(arcsin)
投稿者---かずま(2004/10/29 13:05:01)


>   for (i = 1; t > EPSILON; i++) {
>       i2 = i * 2;
>       t *= i2 * (i2 - 1) * x * x / (4 * i * i);
>       s += t / (i2 + 1);
>   }

無駄が多いので、ちょっと修正。

    x = x * x / 2;
    for (i = 1; t > EPSILON; i++) {
        t *= (i * 2 - 1) * x / i;
        s += t / (i * 2 + 1);
    }



No.17632

Re:逆関数(arcsin)
投稿者---k2(2004/10/29 19:05:32)


/*
    SampleSource
double asin(double x){

    double result,a,b;
    int n;
    
    result = x;
    
    for(n=1;n>=N;n++){
        a = pow(x,2*n+1);
        b = sum(1,n)/sum(2,n);
        result += a + b;
    }
    return result;
}

レスありがとうごさいます。
あまり高精度でなくていいのでこんな感じになりました。
プログラム得意でないので変と思われるかもしれませんが。
sum関数は奇数和、偶数和を計算します。Nは何項目まで加算するかです。
1に近いと収束しにくいということ知らなかったので考慮してませんでした。



No.17633

Re:逆関数(arcsin)
投稿者---k2(2004/10/29 19:10:35)


><pre>
> for(n=1;n>=N;n++){
すいません。不等号反対でした。<=です。
</pre>