人に聞けない痔の悩み、これでスッキリ >>

C言語で円周率を求めるプログラムを作りたいのですがわかりません。
どなたか教えていただけないでしょうか。

このQ&Aに関連する最新のQ&A

A 回答 (5件)

C言語と円周率をキーワードにして検索をかけると、参考になるサイトが検索できますよ。


以下のURLを参照してください。具体的な、コーディングの例ものっています。
http://www1.cts.ne.jp/~clab/hsample/Math/Math1.h …
http://www.geocities.jp/kaname78web/pi.html
http://www.ss.cs.meiji.ac.jp/CCP051.html
    • good
    • 0
この回答へのお礼

ありがとうございます。
参考にさせていただきます。

お礼日時:2010/05/08 19:36

念のために書いておきますが、ANo.3で挙げたプログラム例は真に受けないでください。


学校の課題とかだったら、多分怒られます。
    • good
    • 1
この回答へのお礼

大丈夫です。
わざわざありがとうございました。

お礼日時:2010/05/11 20:48

>小数点以下6桁で表示されました。


>これはどうしてなのか教えていただけませんか?

printf()の書式"%f"で、精度の記述を省略しているからです。
時間があれば、printf()の書式指定文字列について
調べてみてください。
    • good
    • 0
この回答へのお礼

ありがとうございいます。
理解できました。

お礼日時:2010/05/08 20:10

小数点以下何桁まで求めたいのでしょうか?


どんなアルゴリズムを使うにせよ、C言語のdouble型で表せる範囲に収まるかどうかで面倒くささが大きく異なります。

【円周率を求めるプログラム例】
#include <stdio.h>
#include <math.h>
int main() {
double p=asin(1.0)*2.0; /* sin(π/2)=1 */
printf("%f\n", p);
}
    • good
    • 1
この回答へのお礼

ありがとうございます。
特に小数点以下何桁までとは決まっていないのですが、
salsberryさんのプログラムを実行してみたところ
小数点以下6桁で表示されました。
これはどうしてなのか教えていただけませんか?
初歩的な質問でごめんなさい。

お礼日時:2010/05/08 19:35

円周率を求めるアルゴリズム自体が、問題ですから、C言語で、記述できる円周率を求めるプログラム自体が無数にあります。

円周率πの話の本を、まず始めに勝ってください。モンテカルロ法など乱数を使って求めるものなど最初に乱数発生プログラムを作る問題から解くなどという方法もあります。円周率の歴史書があるぐらいで、一朝一夕で片付くようなプログラム制作ではありません。検索してもC言語での回答はないと思います。まずは、円周率を知ることです。
    • good
    • 0
この回答へのお礼

返答ありがとうございました。
円周率についてもう少し調べてみることにします。

お礼日時:2010/05/08 19:38

このQ&Aに関連する人気のQ&A

円周率」に関するQ&A: 円周から半径を求める

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aを見た人はこんなQ&Aも見ています

このQ&Aを見た人が検索しているワード

このQ&Aと関連する良く見られている質問

Q三角関数の記述の仕方

タイトルそのまんまなんですが、三角関数はC言語ではどのように記述すればいいでしょうか?
角度にラジアン表記でπ(パイ)を使いたいんですが、その表記方法もわかりません。
僕の持っている本に載ってなかったので質問させていただきました。
よろしくお願いします。

Aベストアンサー

C言語で三角関数を使うためには、math.h をインクルードする必要があります。使い方は例えば、こんな感じです。

#define M_PI 3.14159265358979 /* 円周率 */

double x, y, theta;

theta = M_PI / 4.0;
x = cos(theta); /* sin,cos,tanの引数は弧度法の角度です。*/
y = sin(theta);

πは上記の例のように自分で定義して使ってください。

Q円周率の計算式って何ですか?

3.141592・・・と円周率がありますが、円周率ってどういう式をたてて計算すればあんなものが出てくるんでしょうか?

それともここでは回答できないような相当複雑で難しい式なのですか?

Aベストアンサー

円周と直径を測って 円周÷直径 で円周率を求められます。
計測に誤差があっては正確な答えは出ません。

Qπ

VC++ で、πを、使うにはどうしたらいいのでしょうか?3.141・・・・と打つしかないんでしょうか?

Aベストアンサー

無理数なのですから限界はあります。
よって#defineで定義するのが普通です。
doubleが8バイト
long double(Linux)が10バイトと
有効桁数が限られているので普通に使うには
#defineの定義で問題ないはずです。

あとは公式でπ/4=arctan(1)とか。
より高精度にしたいのでしたらスーパーパイでも使って調べてはどうでしょうか。
http://rd.vector.co.jp/soft/win95/edu/se022882.html

参考URL:http://rd.vector.co.jp/soft/win95/edu/se022882.html

QVisial C++おけるπの使い方

自宅でCプログラミングの練習をするためVisial C++ 2008を使って
プログラムをしています。y<sin(πx)となった時の
割合などを計算するプログラムで                「M_PIが定義されていない識別子です」
とでてきます。所持している本を参考にしてもM_PI=πとして用いる
と書いてあり、math.hもインクルードしてるので原因が分からなくて
困ってます。Visial c++ではπの使い方には何か別の使い方がある
のでしょうか?よろしくお願いします。
*↓が実際に作ったプログラムです。
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <math.h>

int main(void){
int i,n,count=0;
double x,y,r,error;

srand((unsigned)time(NULL)); /*乱数の初期化*/

printf("How many trials?");
scanf("&d",&n);

for(i=0;i<n;i++){
x=rand()/(RAND_MAX+1.0);
y=rand()/(RAND_MAX+1.0);

if(y<sin(M_PI*x)){
count++;
}
}

r=(double)count/n; /*キャスト演算子を使用*/
error=2/M_PI-r;

printf("Result is %f (Error: %f)\n",r,error);

return 0;
}

自宅でCプログラミングの練習をするためVisial C++ 2008を使って
プログラムをしています。y<sin(πx)となった時の
割合などを計算するプログラムで                「M_PIが定義されていない識別子です」
とでてきます。所持している本を参考にしてもM_PI=πとして用いる
と書いてあり、math.hもインクルードしてるので原因が分からなくて
困ってます。Visial c++ではπの使い方には何か別の使い方がある
のでしょうか?よろしくお願いします。
*↓が実際に作ったプログラムです。
#include ...続きを読む

Aベストアンサー

★アドバイス
・math.hをインクルードする前に『_USE_MATH_DEFINES』定数を define します。

#define _USE_MATH_DEFINES
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <math.h>

int main( void )
{
 :
 return 0;
}
必ず include する前に定義して下さい。

Q漸化式を用いたπを求めるプログラム

下のプログラムの問題がわかりません。教えていただけませんか?

半径1の円に内接する正6・2^n角形の1辺の長さをa(n)とし 

a(n)+1=a(n)/√2+√4-a^2(n)
の式のπの近似値を計算するプログラムを作成しなさい。

 ※()の中は添え字です。
あと√2+√4-a^2(n)の文章は
√のなかに2+√4-a^2(n)の式が入ってる形です。

Aベストアンサー

Option Explicit On
Option Compare Binary
Option Strict On
Option Infer Off 'VB2008以上

Class Q4333288A
Shared Sub Main()
System.Console.WriteLine(CalculatePI(50).ToString())
System.Console.ReadKey(true)
End Sub

Shared Function CalculatePI(Precision As Integer) As Double
Dim pi As Double = SideLength(Precision) * 6 * Math.Pow(2,Precision) / 2
Return pi
End Function

'クラスに分割しようと思ったけど,関数名が思いつかないので放置
Shared Function SideLength(n As Integer) As Double
If n < 0 Then

Throw new System.ArgumentOutOfRangeException()

End If

If n = 0 Then
Return 1.0
End If

Dim temp As Double = SideLength(n-1)
Return temp / Math.Sqrt(2+Math.Sqrt(4-Math.Pow(temp,2)))

End Function

End Class

'a(n)+1=a(n)/√2+√4-a^2(n)
'これじゃ式が全然通じないよ
'a(n)+ 1 = ( a(n) / Math.Sqrt(2) )+ Math.Sqrt(4) - Math.Pow(a(n),2)
'とか
'a(n)+ 1 = a(n) / Math.Sqrt(2 + Math.Sqrt(4) - Math.Pow(a(n),2))
'って読んじゃった。
'せめて
'a(n+1)=a(n)/√(2+√(4-(a(n))^2))
'と書かないと。
'a(n+1) = a(n) / Math.Sqrt(2+Math.Sqrt(4-Math.Pow(a(n),2)))
'だともっと嬉しい。

'VBA/VB6だと後から言われても回答には戻ってこないつもり

'問1:この漸化式を導出せよ

'わざわざ面積を求めんでも。周囲の長さでいいじゃん

Option Explicit On
Option Compare Binary
Option Strict On
Option Infer Off 'VB2008以上

Class Q4333288A
Shared Sub Main()
System.Console.WriteLine(CalculatePI(50).ToString())
System.Console.ReadKey(true)
End Sub

Shared Function CalculatePI(Precision As Integer) As Double
Dim pi As Double = SideLength(Precision) * 6 * Math.Pow(2,Precision) / 2
Return pi
End Function

'クラスに分割しようと思ったけど,関数名が思いつかないので放置
Shared Function SideLength(n...続きを読む

Qマチンの公式による円周率のプログラム

この前、学校の授業でマチンの公式による円周率の計算をするプログラムを以下の方針で考えました。ここで、atanを求めるユーザー定義関数を作りたいのですが、途中までは考えたのですが以下の空欄の部分が、よく分かりません。
【方針】1.数列a(k)=±(1/2k-1)*x^(2k-1)(k=1,2,…)の漸化式を作る。(a(k)のkは添え字です)
2.a(1)+a(2)+a(3)+…+a(N)の値をatan(x)の近似値とする。
(1,2,3,…,Nは添え字です)

(プログラムの一部)→atanの近似値を求める関数
double Atan(double x)
{
double s=_,a=_,kk;
int k; //添え字用
for(k=1;k<=x;k++)
{s_; //多分式が入る。
kk=(double)k;
a_; //多分式が入る。
}
return s;
}

下線部に適当な文字や式を入れて、この関数を完成させてください。(ヒントをください)
※できれば、このプログラムの形は変えないで、下線部のみを埋めてください。

この前、学校の授業でマチンの公式による円周率の計算をするプログラムを以下の方針で考えました。ここで、atanを求めるユーザー定義関数を作りたいのですが、途中までは考えたのですが以下の空欄の部分が、よく分かりません。
【方針】1.数列a(k)=±(1/2k-1)*x^(2k-1)(k=1,2,…)の漸化式を作る。(a(k)のkは添え字です)
2.a(1)+a(2)+a(3)+…+a(N)の値をatan(x)の近似値とする。
(1,2,3,…,Nは添え字です)

(プログラムの一部)→atanの近似値を求める関数
double Atan(double x)
{
double s=_,a=_,k...続きを読む

Aベストアンサー

グレゴリ級数
Σ[n=0,∞]((-1)^n / (2n + 1)) * x^(2n + 1)
グレゴリ級数をN項まで展開する場合、n=0~N-1になります。
Σ[n=0,N-1]((-1)^n / (2n + 1)) * x^(2n + 1)

問題と成っている関数の下線を埋めてもプログラムは完成しません。
根本的に間違えがあります。

グレゴリ級数を素直に書いた場合。
double MyAtan(double x)
{
 double s = (1)___;
 int n;

 for (n = 0; n < N; n ++) {
  s (2)___
 }
 return s;
}
と言う形状が一般的です。
Σは総和です。
Σ[n=0,N-1]((-1)^n / (2n + 1)) * x^(2n + 1)
の場合、
> for (n = 0; n < N; n ++) {
の様に0~N未満までループさせます。
この時の各nで式「((-1)^n / (2n + 1)) * x^(2n + 1)」を計算し全てを加算したのが総和です。
よって、(2)の下線には式「((-1)^n / (2n + 1)) * x^(2n + 1)」が入る事になります。
「s = s + 加算式」or 「s += 加算式」
また、Σ[n=0,N-1]の初項(n=0)は0.0に対してn=0時の数値を加算したものと考えられます。
よって、(1)には0.0が入ります。
double MyAtan(double x)
{
 double s = 0.0;
 int n;

 for (n = 0; n < N; n ++) {
  s += 式
 }
 return s;
}
式には「((-1)^n / (2n + 1)) * x^(2n + 1)」が入ります。
乗数はpow関数を使用します。
・テクニックとして
初項がxと分かっているので
double MyAtan(double x)
{
 double s = x; <-- 初項(n=0)分が計算済み
 int n;

 for (n = 1; n < N; n ++) { <-- n = 1と成っている
  s += 式
 }
 return s;
}
とすると複雑な計算の回数が1回減り、少し速くなります。
この関数を大量に実行しない限り、測定誤差の範囲ですが。
また、「(-1)^n 」の部分も条件文にし、powを使わない方が速くなります。

まずは素直に作ってみるのが良いでしょう。

グレゴリ級数
Σ[n=0,∞]((-1)^n / (2n + 1)) * x^(2n + 1)
グレゴリ級数をN項まで展開する場合、n=0~N-1になります。
Σ[n=0,N-1]((-1)^n / (2n + 1)) * x^(2n + 1)

問題と成っている関数の下線を埋めてもプログラムは完成しません。
根本的に間違えがあります。

グレゴリ級数を素直に書いた場合。
double MyAtan(double x)
{
 double s = (1)___;
 int n;

 for (n = 0; n < N; n ++) {
  s (2)___
 }
 return s;
}
と言う形状が一般的です。
Σは総和です。
Σ[n=0,N-1]((-1)^n / (2...続きを読む

Qfloat型とdouble型の変数の違いを教えてほしいです

float型とdouble型の変数の違いを教えてほしいです
2Dゲームを作っててdoubleの変数を使ってたんですが使ってはだめだと先輩に言われたんです。
理由を聞いたら、先生が「doubleは使わないほうがいい」と言われたらしくてちゃんとした理由がわかりませんでした。
それを知って何をするということではないんですが、気になって調べても出てこなかったので質問させてください。
まだゲーム作りを始めたばっかりでぜんぜん詳しくないですが教えてくれたら助かります。

Aベストアンサー

doubleとfloatでは、精度が違い、そのためメモリに占める大きさも違います。
また、一般的には、桁が多いとその分計算時間がかかります。
ですから、精度が必要ない場面では、floatを使う、というのも一つの考えかたです。

ですが、実際には「一概に言えない、処理系依存」です。

以前は全てCPUで計算していたので、精度=計算量でした。
しかし、最近では浮動小数点演算専用の回路が付いているケースが多く、計算時間は同じだったり、doubleに変換が必要でその分floatの方が遅かったり、floatでの演算はより高速にできたり、と様々です。
32bitCPUでは、32bitのfloatの方が扱いやすいでしょうが、64bitCPUでは64bitのdoubleの方が扱いやすいかもしれません。
Cのmath.hで使える標準関数はdouble型のものがほとんどです。三角関数は2Dのゲームでも使う機会が多いのではないでしょうか。sinもcosもdouble型です。内部演算は当然doubleですので、変数にfloatを使ったからと早くはならず、むしろfloat型の変数に入れるときに暗黙の型変換が発生する分遅くなる可能性もあります。

そういった背景を考え検討した結果、floatを使う方がよい、と判断したのならいいのですが、「先生に言われた」では理由になりません。
聞けるのなら、その先生に理由を聞いてください。真意がわからないうちは、鵜呑みしないことです。

doubleとfloatでは、精度が違い、そのためメモリに占める大きさも違います。
また、一般的には、桁が多いとその分計算時間がかかります。
ですから、精度が必要ない場面では、floatを使う、というのも一つの考えかたです。

ですが、実際には「一概に言えない、処理系依存」です。

以前は全てCPUで計算していたので、精度=計算量でした。
しかし、最近では浮動小数点演算専用の回路が付いているケースが多く、計算時間は同じだったり、doubleに変換が必要でその分floatの方が遅かったり、floatでの演算はより高速...続きを読む

Q振り子をオイラー法で

プログラムで、振り子のヒモの長さ、重さ、角度を自由に設定し、振り子のアニメーションが表示されるようにしようと考えています。
普通の運動方程式での振り子の運動の表示はできたのですが、
オイラー法やルンゲクッタ法を使って導き出した振り子の動きも表示したいと考えています。
ところが、どうやってオイラー法を振り子の運動方程式に応用すれば、振り子のX、y座標が分かるのか?ということが、勉強不足でどうにもわかりません…

どなたか、ヒントだけでも教えていただけると幸いです。

Aベストアンサー

 #1です。
 補足を拝見しました。

 運動方程式で、途中で速度をかませてよいのでしたら、オイラー法や修正オイラー法を使うことができます。この方法は、常に、速度⇒変位の順に解いていくものです。
http://www.asahi-net.or.jp/~hy9n-knk/eq_simu.htm

 そのほかに、邪道かもしれませんが、速度の計算を一度だけで省略する方法もなくはありません。
 2階微分方程式を差分方程式の形に直すと、初期変位として2点が必要になります。1点は問題自体に与えられているものを使いますが、2点目は、速度をかませて求めた変位を使います。あとは常に最初の2点が確保されますので、順に数値計算を進めていくことができます。

 なお、オイラー法を使う場合は、誤差がかなり大きくなってくるので注意してください。
http://maya.phys.kyushu-u.ac.jp/~knomura/education/numerical-physics/text5/node2.html

 また、ルンゲ・クッタ法でも解くことができます。
 運動方程式に適用した例を掲載したサイトがありましたので紹介します。
http://www6.ocn.ne.jp/~simuphys/runge-kutta.html

 #1です。
 補足を拝見しました。

 運動方程式で、途中で速度をかませてよいのでしたら、オイラー法や修正オイラー法を使うことができます。この方法は、常に、速度⇒変位の順に解いていくものです。
http://www.asahi-net.or.jp/~hy9n-knk/eq_simu.htm

 そのほかに、邪道かもしれませんが、速度の計算を一度だけで省略する方法もなくはありません。
 2階微分方程式を差分方程式の形に直すと、初期変位として2点が必要になります。1点は問題自体に与えられているものを使いますが、2点目は、速度を...続きを読む

Qdoubleは常に%lfとするべきなのか

c言語についての質問です.疑問と自分なりの解答を書くので訂正,アドバイスなどを頂けるとありがたいです.

以下のプログラムのようにprint関数でdoubleのフォーマットを%fとします.scanのフォーマットを%lfとします.問題なく通ります.しかし,scanの方のフォーマットを%fにすると
format ‘%f’ expects type ‘float *’, but argument 3 has type ‘double *’
と警告が出て,プログラムも正常にaに値を格納しません.なぜでしょう?

これは,変数ならfloat-double間の拡張をコンパイラが勝手にやってくれるが,ポインタの拡張は勝手にやれないから駄目,という理解でよろしいのでしょうか.

このことから,double変数の表示には%fでもいいが,%lfを常に使う方が正統な書き方だという理解でよろしいのでしょうか.常に%lfを使うと何か問題なのでしょうか.

お返事お待ちしております.

#include <stdio.h>
int main()
{
double a = 2.5;
char in_line[50];
fprintf(stdout, "a is %f\n", a);
fprintf(stdout, "type any double: ");
fgets(in_line, sizeof(in_line), stdin);
sscanf(in_line, "%lf", &a);
fprintf(stdout, "a is %f\n", a);
return 0;
}

c言語についての質問です.疑問と自分なりの解答を書くので訂正,アドバイスなどを頂けるとありがたいです.

以下のプログラムのようにprint関数でdoubleのフォーマットを%fとします.scanのフォーマットを%lfとします.問題なく通ります.しかし,scanの方のフォーマットを%fにすると
format ‘%f’ expects type ‘float *’, but argument 3 has type ‘double *’
と警告が出て,プログラムも正常にaに値を格納しません.なぜでしょう?

これは,変数ならfloat-double間の拡張をコンパイラが勝手にやってくれるが...続きを読む

Aベストアンサー

まず、引数の数が変えられる「可変長引数」というのがあります。
scanfもprintfも可変長引数の関数です。
C言語の場合、この可変長引数は次の特徴があります
(1)引数として指定すると、int以下の整数はintに、double以下の実数はdoubleに型変換されます
(2)関数側では、どんな引数が指定されたか、知ることができません。

(1) はprintfの%f に関係があります。
float f;
double d;
printf("%f %f",f,d) ;
とあった場合、(1)のルールによって
printf("%f %f",(double)f,d) ;
と等価になります。
%fの対象をfloatとdoubleとで区別する必要がありません。
どちらもdoubeになるのですから


(2)はscanfの%fと関係します。
引数の型や数を知ることができないので、別な方法で知ります。
その方法の一つが、「別の引数で、数や型を指定する」というものです。
scanf,printfの場合、書式文字列中の %* の数と型で判断します。

scanf("%f", &d) ;
だと、 %f なので、1つのfloat * が指定されている、と判断します。つまり
scanf("%f", (float *)&d) ;
です。そして、読み込んだ値をsizeof(float)分、ポインタが示すアドレスに書き込みます。
一般にsizeof(float)<sizeof(double)なので、変数dの領域の一部が書き変わるだけです。
読み出した値は正しく変数dには納まりません。

scanf("%lf", &d) ;
だと、 %lf なので、1つのdouble * が指定されている、と判断します。つまり
scanf("%lf", (double *)&d) ;
です。そして、読み込んだ値をsizeof(double)分、ポインタが示すアドレスに書き込みます。
こちらは、型と内容が一致するので、正しく変数dに納まります。


一部コンパイラは、書式文字列と引数との対応を調べて警告を出しますが、書式文字列が変数で指定されている場合等では、警告も出ません。
char scanFormat[STRMAX] ;
/* scanFormatに書式文字列を設定 */
scanf( scanFormat, &a);


>double変数の表示には%fでもいいが,%lfを常に使う方が正統な書き方だという理解でよろしいのでしょうか
> 常に%lfを使うと何か問題なのでしょうか.

むしろ、%fの方が正統です。
もともとprintfに%lfは不要ですし、存在していませんでした。
ところが、scanfと混同して「%lfが正しい」と考える人があまりに多かったので、後から規格に追加されました。

C99以降の規格に準じたコンパイラなら、どちらを使っても同じです。
それ以前のコンパイラでも、独自に%lf=%fとして処理しているものもありますが、%fとして動作しない場合もあります。
http://www.kijineko.co.jp/tech/superstitions/printf-format-for-double.html

まず、引数の数が変えられる「可変長引数」というのがあります。
scanfもprintfも可変長引数の関数です。
C言語の場合、この可変長引数は次の特徴があります
(1)引数として指定すると、int以下の整数はintに、double以下の実数はdoubleに型変換されます
(2)関数側では、どんな引数が指定されたか、知ることができません。

(1) はprintfの%f に関係があります。
float f;
double d;
printf("%f %f",f,d) ;
とあった場合、(1)のルールによって
printf("%f %f",(double)f,d) ;
と等価になります。
%fの対象をfloatと...続きを読む

QC言語 配列の長さの上限

C言語で配列Array[N]の長さNの上限っていくらなんでしょうか?
もし可能なのであれば上限を2147483647にしたいのですが、方法を教えてください。

Aベストアンサー

そもそもWindowsの32bit版はアプリが仮想メモリ空間を2GBしか使えません。2GBを超えるには64bit版が必要です。
たとえ64bit版OSだとしても添え字が2147483647って、単純なintの配列だとしても4x2147483647=8GB必要ですね。実メモリ16GBとかのPCを用意しますか?
そもそも配列で2147483647個必要なアルゴリズムに問題ありだと思います。


このQ&Aを見た人がよく見るQ&A

人気Q&Aランキング