C言語関係掲示板

過去ログ

No.43. πの定義と実数での誤差


はじめまして。
今現在VC++をつかっているのですが、

.....

double x , a , b;
M_PI = 3.1415;
x = 90*M_PI/180;
a = sin(x);
b = cos(x);

........

としている場合、
sin(x)の値は1と帰ってくるのですが、
cos(x)の値が帰ってきません。

math.hをもちろんインクルードしています。


どうすればいいのでしょうか?
解決策があればよろしくお願いします。


こんにちは、ともじです。

M_PI = 3.1415; としているので、誤差が生じているのではないでしょうか。
VC++は持ち合わせないのですが、math.hに ? を#defineで宣言している部分
があると思うので、そのdefine値を使うと誤差は消えると思います。


>M_PI = 3.1415; としているので、誤差が生じているのではないでしょうか。
>VC++は持ち合わせないのですが、math.hに ? を#defineで宣言している部分
>があると思うので、そのdefine値を使うと誤差は消えると思います。

レスありがとうございます。
早速やってみた結果、math.hは探しましたが、その中での設定では?の設定
を探し出せませんでした。
その中にはsin,cos,tan....等の基本的な関数がのっていました。
そこで、M_PIの値をもう少し細かくしてみました。
M_PI=3.1415926535;
として計算してみましたが、やはり値は帰ってきませんでした。
これはどうしようもないのでしょうか?
なんでもすいませんが、もしmath.hのなかで、どこに?の設定を書いているのか
ご存知でしたら、ぜひ教えてもらえないでしょうか?
よろしくお願いします


VC++は ? がない?そうですか。
ちなみに、私の環境では以下です。

LSIC            :      #define PI      3.1415926535897932386
Turbo C++ V.4   :      #define         M_PI        3.14159265358979323846
BCB V.4         :      #define         M_PI        3.14159265358979323846


ところで、実際に実行すると、
x = 90*M_PI/180;
b = cos(x);
b は何になりますか。


>VC++は ? がない?そうですか。

私もVC++を持っているので調べてみました。
そうするとなぜかやっぱりありませんでした。

手持ちのANSI C言語辞典で調べたところPIに関する記述は
ありませんでしたのでVC++では用意をしていないのでしょう。
ちょっと不便な気も、、、、。
MSDNでも調べてみたもののそれに該当するような記述は
見あたりませんでした。(単に探し方が悪かっただけかも、、)
要するに処理系依存なのでしょう。

ちなみにGCCでは
#define PI  3.14.....
とPIで宣言されていました。
バラバラなのですね。


>ところで、実際に実行すると、
>x = 90*M_PI/180;
>b = cos(x);
>b は何になりますか。

bは4.4896592167739e-011
という値になります。
これは大変もうしわけないのですが、ほかの人たちの意見によると、
とても小さい値だということです。
(すいませんほかの掲示板にも書き込みをしてしまいました。ともじさんの意見が
気に食わないということではないです。初心者だったものですから、暗黙の了解があるとは思いませんでした。失礼なことをしてすいません。)

つまり値はちゃんと返ってきているということになりますよね?
それであとは使い方しだいだと判断したのですが、いかかでしょうか。


> bは4.4896592167739e-011
> という値になります。

これですと、本当に小さな値ですので誤差の範囲ですね。
ちなみに、Turbo C++ V.4 : #define M_PI 3.14159265358979323846
で実行させると、 6.123032e-17 になります。

> つまり値はちゃんと返ってきているということになりますよね?
> それであとは使い方しだいだと判断したのですが、いかかでしょうか。

つまりそういうことですね。
この結果を %e ではなく %f で表示させると、0.000000 になる思います。
要はほぼ、0.0 なわけです。

最初から値をきちんと聞いておくべきでしたね。ちょっと回り道してしまったかな。
でも、VC++に?の宣言がないのは意外でしたが勉強になりました。

> (すいませんほかの掲示板にも書き込みをしてしまいました。ともじさんの意見が
> 気に食わないということではないです。初心者だったものですから、暗黙の了解があ
> るとは思いませんでした。失礼なことをしてすいません。)

暗黙の了解と言うのは、複数の掲示板に同じ内容を書き込むのは失礼
と言うことですか。
すっきりしない答えが返ってきたときには他の掲示板を利用するのもいいと
思いますよ。


VC++のCos 関数では、

角度の単位を度からラジアンに変換するには、度に?/180 を掛けます。ラジアンから度に変換するには、ラジアンに 180/?を掛けます。

とありましたが、つまり、M_PI = 3.1415;は不要と言う事でしょうか?


> VC++のCos 関数では、
>
>角度の単位を度からラジアンに変換するには、度に?/180 を掛けます。ラジアンから度に変換するには、ラジアンに 180/?を掛けます。
>
>とありましたが、つまり、M_PI = 3.1415;は不要と言う事でしょうか?
>

ともじさんのような環境下では
M_PI = 3.1415;
というような設定はいらないとおもいます(math.hファイルの中に最初から?の設定があるので)が、
VC++環境下では?の設定がないらしいので、個別に?の設定をする必要があるらしいです。


>VC++環境下では?の設定がないらしいので、個別に?の設定をする必要があるらしいです。

どうもありがとうございました。納得しました。
それと、やはり、%f でした。
生まれて初めてのCの書き込み緊張しました。

おしゃべり掲示板に書き込み出来ないと書いたのですが、入れ方の間違いだったみたいです。ともじさんすいません。


>>VC++環境下では?の設定がないらしいので、個別に?の設定をする必要があるらしいです。

VCに?の設定は本当にないのでしょうか?
可能性としてmath.h以外のファイルにないのかな〜?。
F3 の検索で
名前 *.h
含まれる文字列 3.1415
探す場所 VCのincludeフォルダのパス(アドレス)
で検索してみてもらえませんか?
すいません、ど〜しても?の値がないっていうのが
信じられないもので。


>VCに?の設定は本当にないのでしょうか?
>可能性としてmath.h以外のファイルにないのかな〜?。
>F3 の検索で
>名前 *.h
>含まれる文字列 3.1415
>探す場所 VCのincludeフォルダのパス(アドレス)
>で検索してみてもらえませんか?
>すいません、ど〜しても?の値がないっていうのが
>信じられないもので。

上記の検索法でも見つからなかったのでハードディスク丸ごと
検索にかけてみたのですが、
ヘッダーファイル関連では
LSIC86 試食版
Borland C++ Compiler 5.5
gcc(cygwin)
の"math.h"ヘッダーファイルしかヒットしませんでした。

Visual Studio(Enterprise) 6 関連ではわずかにVisual Basic関連の
ファイルがヒットしただけで他は皆無に等しかったです。
(ちなみにEnterpriseツール以外はフルインストールしてます)


>名前 *.h
>含まれる文字列 3.1415
>探す場所 VCのincludeフォルダのパス(アドレス)
どうもないみたいです。
ところで、どうやっても、cosでも、sinでも、値がかえってきますが?
エラーなしでcosの値だけかえったこなかったというのは、、、どうゆうことでしょ?
超初心者には不明です。
ちなみに、3.1415で実行すると%fで、0.000046でした。


>名前 *.h
>含まれる文字列 3.1415
>探す場所 VCのincludeフォルダのパス(アドレス)
どうもないみたいです。
ところで、どうやっても、cosでも、sinでも、値がかえってきますが?
エラーなしでcosの値だけかえったこなかったというのは、、、どうゆうことでしょ?
超初心者には不明です。
ちなみに、3.1415で実行すると%fで、0.000046でした。


?のあるMATH.Hでincludeしても、
3.1415では、0.000046でした。
(念のため、MATH.Hは変名して、includeしました。)


>?のあるMATH.Hでincludeしても、
>3.1415では、0.000046でした。
>(念のため、MATH.Hは変名して、includeしました。)

<pre>
#include <stdio.h>
#include <math.h>
#define PAI 3.1415926535

int main(void)
{
double x, a, b;

x = 90 * PAI / 180;
a = sin(x);
b = cos(x);
printf(" a = %f, b = %f\n", a, b);
printf(" a = %g, b = %g\n", a, b);
printf(" a = %e, b = %e\n", a, b);
return 0;
}
</pre>
/* 注意 PAIは私が勝手に作ったものです。
%の後の文字が曲者ですな。
*/


> %の後の文字が曲者ですな。
>*/

defineでやってみました。おもしろいですね!!
初心者は、こうやって勉強していくのもいいものです。


>ところで、どうやっても、cosでも、sinでも、値がかえってきますが?
>エラーなしでcosの値だけかえったこなかったというのは、、、どうゆうことでしょ?

値じたいはかえってきました。
すごく小さい値で4.4896592167739e-011
という値です。
私はプログラム上で、たとえば

double x = 90*M_PI/180;
double b = cos(x);

if(b == 0)
{
......
}
などうという条件文をかいていたのですが、
cos(x)の値が非常に小さい値で、0(double型では)でなかったために
値が帰ってきていないと思い込んでました。
この掲示板などにより、4.4896592167739e-011
という値が非常に小さい値だということがわかったので、
値が返ってきているが条件を満たさないということに気がついた次第です。
すいません。


了解しました。
ちなみに、
3.1415926535897932386
では、
6.123032e-017

3.1415926535
では、
4.489659e-01
でした。
おかげさまで、大変勉強になりました。

戻る


「初心者のためのポイント学習C言語」 Last modified:2001.10.5
Copyright(c) 2000-2002 TOMOJI All Rights Reserved