大学の講義で電子計算機概論という科目があるのですが、最近その講義の中でレポートが出題されました。「円周率(π)の多数桁計算をコンピュータ内で実現するためにはどのような方法があるか?」というものなのですが、サッパリわかりません。友人たちもみな頭をかかえています。どなたか分かり安く教えてください。または、ヒントをください。お願いします。

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

A 回答 (3件)

以前.πというペンネームでどなたかが数万桁の演算を行っていたプログラムがPC-VANに掲載されていたのですが.今はしりません。


円周率の計算は.一つはモンテカルロ法という方法で.2次元平面に乱数で(乱数の作り方にコツがある。組み込み関数の乱数を使うと疑似乱数の為に答えにならない)点を打ち.何点かヒットするかを数える方法
もう一つは.多角形の内円と外円を求めその間に真の円がある方法
最後に.真円に内接する多角形と真円に外接する多角形を求める方法
ぐらいだったかな?。コンピョーターの教材として良く使われる内容です。コンピューターソフト入門とか.入門フォートランあたりに出ていませんか。
    • good
    • 0
この回答へのお礼

詳しいことを教えてもらえたのでとても参考になり、調べることが楽になりました。感謝してます。ありがとうございました。

お礼日時:2001/07/01 22:41

πといえばπのページと東大の金田研究室ですな。



http://www.super-computing.org/index-j.html

参考URL:http://hp.vector.co.jp/authors/VA014765/pi/index …
    • good
    • 0
この回答へのお礼

教えていただいたページがとても参考になりました。ありがとうございました。

お礼日時:2001/07/01 22:39

検索サイトで、「円周率 アルゴリズム」と検索してみてはどうですか。



Yahoo!Japan検索結果のアドレスです。

http://google.yahoo.co.jp/bin/query?p=%b1%df%bc% …
    • good
    • 0
この回答へのお礼

ありがとうございました。何とかレポートを書けそうです。感謝します。

お礼日時:2001/07/01 22:37

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

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

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

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

Qモンテカルロ法 円周率

モンテカルロ法で円周率を求めたいのですが
C++でプログラムを実行までは出来るんですけど
それをグラフにする方法が分かりません。
(扇形みたいなヤツです。点々が沢山付くヤツです。)

あと「モンテカルロ法から演習路津が求まる原理」と
「エクセルとCプログラミングで円周率を求めた時の
比較の仕方」も教えて頂きたいのです…。

沢山聞いてしまって、本当にすいません。
なにとぞ、初心者なのでよろしくお願いします。

Aベストアンサー

>モンテカルロ法から演習路津が求まる原理
ある面積のある部分に、適当に(一様になるように)何かを落としたとしたら、
その全体の面積の一部分に何かが落ちてくる確率は全体に落ちてくる確率(1)との比率になるけど、その比率は、その面積の部分の面積と全体の面積の比率になる
ということから、逆に
1/4円とそれを包む正方形の面積の比率は、そこに適当にモノを落としてその結果から比率を求めることができるということです。

Qpython、区分求積法を用いて円周率πを求めるプログラム

python2.7で区分求積法でπを求めるプログラムを作成したのですが、精度と時間があまりよくないです。
改善するとしたらどうすればいいでしょうか?
(申し訳ありませんがインデントがうまくいかないため"_"を使っています。エディタ等で置換してください。)
回答よろしくお願いします。m(_ _)m
________________________________________________________________________

#-*- coding: utf-8 -*-
def cal_pi():
_r1 = 0
_r2 = 0
_for i in xrange(1,1000):
__r1 += mysqrt(1000000-i**2)
_for k in xrange(0,999):
__r2 += mysqrt(1000000-k**2)
_r = float((r1+r2)/500000)
_return r

def mysqrt(x):
_#初期値の設定
_t = 1
_i = -1
_while x > t:
__t = t*100
__i += 1
_r1 = 5*(10**i)
_#Newton_method
_prer = r1
_r = float(r1 - ((r1**2)-x)/(2*r1))
_while round(r,10) != round(prer,10):
__prer = r
__r = float(r - ((r**2)-x)/(2*r))
_return r

python2.7で区分求積法でπを求めるプログラムを作成したのですが、精度と時間があまりよくないです。
改善するとしたらどうすればいいでしょうか?
(申し訳ありませんがインデントがうまくいかないため"_"を使っています。エディタ等で置換してください。)
回答よろしくお願いします。m(_ _)m
________________________________________________________________________

#-*- coding: utf-8 -*-
def cal_pi():
_r1 = 0
_r2 = 0
_for i in xrange(1,1000):
__r1 += mysqrt(1000000-i**2)
_for k in...続きを読む

Aベストアンサー

> とても速く正確で驚きました!

実は旧いタイプのプログラマ(例えばC/C++、Java、Pascal、VBA等を得意とする)なんかはリスト内包表記を「分かりづらい」と言うんで嫌う傾向があるんですね。
「リスト内包表記」はHaskellと言う、「関数型言語」と言われるパラダイムに属する言語から借りてきた機能です。

Haskell(リストとリスト内包表記):
https://ja.wikipedia.org/wiki/Haskell#.E3.83.AA.E3.82.B9.E3.83.88.E3.81.A8.E3.83.AA.E3.82.B9.E3.83.88.E5.86.85.E5.8C.85.E8.A1.A8.E8.A8.98

んで、確かに従来の手続き型/オブジェクト指向系の言語が備えてる機能とは見た目からして違う。
ただし、Pythonの場合、実はフツーにfor文でループを回すよりこっちの方が「実行速度が速い」んです。つまり、リスト内包表記には最適化が施されているんですね。
(これが意味する事は、Pythonの設計者がユーザーに「リスト内包表記をどんどん使って欲しい」って思ってる、って事です)
まあ、数値計算相手だけ、じゃなくって対象のリストは色々と考えられるんですが、特に今回のケースのように

* 数値の列をリストとして表現可能で、リストの各要素に「何らかの」計算を施さないといけない

場合は、取り敢えず「リスト内包表記の使用」ってのは一考の価値があります。
先に書いた通り、「フツーにforループを書いたコードより高速に動作する」んで、明らかに、「コードが短くなる」以上に実用的なメリットがある、って事だからです。

> sum関数は型変換も自動で行っているということでしょうか?

うーん、型変換・・・考えた事無かったですね(笑)。

>>> sum([1, 2, 3, 4, 5])
15
>>> sum([1.0, 2.0, 3.0, 4.0, 5.0])
15.0
>>>

まあそのまま、です(笑)。
ええと、元コード見る限り、恐らくC系とかの「静的型付け」言語の学習経験があるのかな、とか思ったんですが、Pythonの場合、「静的型付け」ではなくって、「動的型付け言語」って言われるモノに属しています。
これらの言語の特徴は、「実行時に型が決まる」って特徴があるんですね(他にはLisp、Ruby、JavaScript等がある)。
これは「型がない」わけではなくって、型はあるんですが、明示しなくても良い。コードが走る「その時点で」型が決まる、って特徴があるんです。
従って、sumにしても、エラーになるかならないか、「走ってみなけりゃ分からない」って事なんですね(笑)。いずれにせよ、コードを書いてる時点では、「型」は忘れて構わない・・・フツーは、ですね(笑)。

実は、Python3では改善されてるんですが、Python2.xだとちょっと困る事があるんですね。それはこれです。

>>> 1/2
0
>>>

1を2で割ると0になる・・・。これがPython2.xだと困るトコで、Python3以降だと改善されてるトコなんですね。これは答えだと0.5とかそれに類する値が欲しいトコなんですが、これがちょっと「出来の悪いC言語」みたいな値を返してくる(笑)。
Python3以降だと次のようになります。

>>> 1/2
0.5
>>>

Scheme(Lisp言語の一種)だと次のようになります。

> (/ 1 2)
1/2
>

いずれにせよ、「型を意識しなくて良い筈の」動的型付け言語で、「割り算」の時だけ型を意識しなくちゃいけない、ってのは結構不都合なんですよね。
Python2.xの場合、この手の問題を避ける時にやるのが(動的型付けなのに!・苦笑)、C言語で言う「キャスト」ですね。型変換。floatの出番、なんつーのはこの時くらいしかない。

>>> 1/float(2)
0.5

あるいは、僕自身は、参考コードとかであんまfloat使うの見たことないんですが、良くあるケースでは次のように書いて「お茶を濁す」ケースが殆どです。

>>> 1/(2 * 1.0)
0.5

つまり、ワザと「割る数に1.0(float型)をかけてfloatに直して」割る、と言う、結構みっともない(笑)ハックですよね。
こーゆーのがPython2.x系の「欠点」と言えば「欠点」なんです。

さて、そうなると、「どこでキャストするのか」ってのが問題になってきます。
例えば1/2を計算したいとして、

>>> 1/2
0

になっちゃう、ってのは既に見ました。
問題は、です。

>>> float(1/2)
0.0

これをついついやっちゃうんじゃないか、って事ですよね。1/2は元情報がInt(整数型)なんで当然1/2も整数型にならざるを得ないんで0を返します。
この「0をfloatにキャストしても」結果はfloatになるだけで計算結果としては役立たずなんですよ。
つまり、安全策としては「割る数をキャストしないと」意味を成さない、って事です。

>>> 1/float(2)
0.5

「割った後にキャストしても」ダメなんですよね。
さぁ、自分のコードを見なおしてみて下さい。「割った後に」floatに型変換してませんか?「割る数を」キャストしないと、「既に手遅れ」なんです。

Python2.x系だと、この「割る数の」型だけ気をつければ、通常は「型」の事なんざ忘れててもオーケーです。
ドツボになるのは「割り算の時だけ」です。
(しかもPython3.x系だともはやこの辺さえも忘れて大丈夫です)

> とても速く正確で驚きました!

実は旧いタイプのプログラマ(例えばC/C++、Java、Pascal、VBA等を得意とする)なんかはリスト内包表記を「分かりづらい」と言うんで嫌う傾向があるんですね。
「リスト内包表記」はHaskellと言う、「関数型言語」と言われるパラダイムに属する言語から借りてきた機能です。

Haskell(リストとリスト内包表記):
https://ja.wikipedia.org/wiki/Haskell#.E3.83.AA.E3.82.B9.E3.83.88.E3.81.A8.E3.83.AA.E3.82.B9.E3.83.88.E5.86.85.E5.8C.85.E8.A1.A8.E8.A8.98

んで、確かに従来の...続きを読む

Qモンテカルロ法 計算精度

モンテカルロ法で円周率をc++言語でプログラムを作成して求めたのですが、精度要因って何ですか??乱数の乱数らしさでしょうか??

Aベストアンサー

乱数のランダム性(偏りが無いこと、規則性・周期性がないこと、全ての乱数が等確率で発生すること(一様分布))、そしてランダム性が保証されている範囲では、乱数の個数が多いほど計算精度が上がる。

Q情報処理概論

年齢が20以上であれば「あなたは成人です」と表示し20未満なら「あなたは未成年です」と表示する、if文を書けというのがわかりません。どなたか教えていただけますでしょうか?

Aベストアンサー

C言語の場合

if( year >= 20 )
printf("あなたは成人です\n");
else
printf("あなたは未成年です\n");

Tcl/Tkの場合

if{ $year >= 20 } {
puts "あなたは成人です\n"
} else {
puts "あなたは未成年です\n"
}

いずれの場合もyear(または$year)には何らかの値が記録されているものとします。
ここでは答えをまるごと教えるわけにはいかないので、上記のようなエッセンス部分しか提示できません。どのような言語に則って学んでいるにしろ、「もし[条件A]が成立するならば[X]を計算、それ以外は[Y]を計算」というアルゴリズムは上記のような表記になります。その骨組みは

    IF A THEN X ELSE Y

とプログラムするのですが、進んだ言語になると"THEN"を省略してしまいます。上例のC言語とTcl/Tk言語に"THEN"が現れないのはそのためです。昔風のBASIC言語なら、明瞭に"THEN"を記述していました。
詳細な文法は、講義から学び取ってください。

C言語の場合

if( year >= 20 )
printf("あなたは成人です\n");
else
printf("あなたは未成年です\n");

Tcl/Tkの場合

if{ $year >= 20 } {
puts "あなたは成人です\n"
} else {
puts "あなたは未成年です\n"
}

いずれの場合もyear(または$year)には何らかの値が記録されているものとします。
ここでは答えをまるごと教えるわけにはいかないので、上記のようなエッセンス部分しか提示できません。どのような言語に則って学んでいるにしろ、「もし[条件A]が成立する...続きを読む

QBASICでモンテカルロ法

モンテカルロ法で円周率の推定値を計算することを最近習ったのですが、定積分でもそれが可能なのを知り、どうやってプログラムを組めばいいのか分からず、困っています。
例えば、定積分∫[0→1]x^2dx=1/3~0.333([0→1]というのは、積分範囲です。)をモンテカルロ法で計算すると、どういうプログラムを組めばいいのでしょうか?
わかる範囲で書いてみたのですが…積分の範囲をどうやってプログラミングすればいいのか、いまいち分かりませんでした。
教えていただけると、助かります。よろしくお願いします。

RANDOMIZE

INPUT n
SET WINDOW -0.1,1.1, -0.1,1.1
DRAW GRID
SET POINT STYLE 1
LET sumin=0

FOR i=0 TO n
LET x=RND
LET y=RND
SET POINT STYLE 2
IF y<x*x THEN
SET POINT COLOR 4
LET sumin=sumin+1
END IF
! PRINT USING "(%.####, %.####)": x,y
PLOT POINTS: x,y
NEXT i

PRINT 1*1*sumin/n
END

モンテカルロ法で円周率の推定値を計算することを最近習ったのですが、定積分でもそれが可能なのを知り、どうやってプログラムを組めばいいのか分からず、困っています。
例えば、定積分∫[0→1]x^2dx=1/3~0.333([0→1]というのは、積分範囲です。)をモンテカルロ法で計算すると、どういうプログラムを組めばいいのでしょうか?
わかる範囲で書いてみたのですが…積分の範囲をどうやってプログラミングすればいいのか、いまいち分かりませんでした。
教えていただけると、助かります。よろしくお願いします。

...続きを読む

Aベストアンサー

ええと、専門用語では「提案分布」と言うんですが、それが積分範囲を「近似しつつ」かつ「計算が簡単な」分布を目的の積分範囲の外側になきゃいけません。
僕はBASICは良く知らないのですが、つまり擬似コード的にはこう言う事です。

1.積分したい関数(例では0≦x≦1の範囲でのx^2)を設定する。
2.上の「被積分関数」を上手く近似しそうな適当な分布を選ぶ。

とは言っても、実際の「確率分布」ではなくって、この場合「0≦x≦1の範囲」ってのをヒントとして、0≦x≦1、0≦y≦1と言う「正方形」を考えます。これが1の「被積分関数」を上手く囲んでいる事が分かるでしょう。

3.(x, y)の乱数を生成して「提案分布」内に乱数をプロットしていく。
4.3.の乱数がy≦x^2を満たしていたら「当たり」、そうじゃなかったら「ハズれ」として、数をカウントしていく。
5.当たりの数/(当たりの数+ハズレの数)×「提案分布の面積」が目的の被積分関数の面積、になる

こう言うプログラムがオーソドックスな「モンテカルロ法での定積分」の手法となるんではないでしょうか?

ええと、専門用語では「提案分布」と言うんですが、それが積分範囲を「近似しつつ」かつ「計算が簡単な」分布を目的の積分範囲の外側になきゃいけません。
僕はBASICは良く知らないのですが、つまり擬似コード的にはこう言う事です。

1.積分したい関数(例では0≦x≦1の範囲でのx^2)を設定する。
2.上の「被積分関数」を上手く近似しそうな適当な分布を選ぶ。

とは言っても、実際の「確率分布」ではなくって、この場合「0≦x≦1の範囲」ってのをヒントとして、0≦x≦1、0≦y≦1と言う「正方形」を考えます。これが1...続きを読む

Qfortran πについて

算術計算をするために、πを
pi=4.0d0*datan(1.0d0)
で、定数として置こうとしましたが、
エラーで『datanはThis intrinsic function is invalid in constant expressions.』と出てきました。

型はreal*8 で行いました。
どうしたら、定数として置けるのでしょうか??

Aベストアンサー

少なくとも Fortran2003 の Final Committee Draft を見る限り, parameter 文/parameter 属性のどちらにおいても*ある種の*計算は可能です>#3.
例えば
REAL, PARAMETER :: ONE = 1.0, Y = 4.1 / 3.0
とか
PARAMETER (MODULUS = MOD (28, 3), NUMBER_OF_SENATORS = 100)
という文が例として挙げられています.
どちらも = のあとは initialization-expr で, しかも困ったことにこの initialization-expr の例に
4.0 * atan(1.0)
が挙げられてます.
まあ, 質問者の fortran というのがどの規格に対応しているかわかりませんから, Fortran2003 FCD の記述があてはまるかどうかわかりませんが.

Qモンテカルロ法

モンテカルロ法で円周率の推定値を計算することを最近習ったのですが、定積分でもそれが可能なのを知り、どうやってプログラムを組めばいいのか分からず、困っています。
例えば、定積分∫[0→1]x^2dx=1/3~0.333([0→1]というのは、積分範囲です。)をモンテカルロ法で計算すると、どういうプログラムを組めばいいのでしょうか?
わかる範囲で書いてみたのですが…積分の範囲をどうやってプログラミングすればいいのか、いまいち分かりませんでした。
教えていただけると、助かります。よろしくお願いします。


RANDOMIZE

INPUT n
SET WINDOW -0.1, 1.1, -0.1,1.1
DRAW grid
SET POINT STYLE 1
LET sumin=0

FOR i=0 TO n
LET x=RND
LET r=x*x
SET POINT COLOR 2

! PRINT USING "(%.####, %.####)": x,y;
PLOT POINTS: x,y;
NEXT i
PRINT sumin;n
PRINT sumin/n

END

モンテカルロ法で円周率の推定値を計算することを最近習ったのですが、定積分でもそれが可能なのを知り、どうやってプログラムを組めばいいのか分からず、困っています。
例えば、定積分∫[0→1]x^2dx=1/3~0.333([0→1]というのは、積分範囲です。)をモンテカルロ法で計算すると、どういうプログラムを組めばいいのでしょうか?
わかる範囲で書いてみたのですが…積分の範囲をどうやってプログラミングすればいいのか、いまいち分かりませんでした。
教えていただけると、助かります。よろしくお願いします。

...続きを読む

Aベストアンサー

質問のソースはカテゴリ違いですが、
アルゴリズムに関する質問だと思いますので、
言語に依存しない部分で回答します。

f(x) = x*x の関数を、0~1の区間で積分ですね。

まず、y 軸の範囲を考えます。
グラフを書けば分かりやすいと思います。

f(0) = 0 から始まり、xが増加すれば f(x) も増加。
f(1) = 1 で終わりなので、y 軸の範囲は 0~1 とします。

---------------------------------
ループ回数 n の入力

カウント sumin を初期化

ループ開始(n 回ループ)

x に 0~1の乱数を代入(積分区間)

y に 0~1の乱数を代入(上記で計算した範囲)

ポイント(x, y) が求める面に入っていればカウントする
つまり、y < x*x の場合はカウント sumin に 1 を加算

ループ終了

結果は、(乱数範囲の面積) × (カウント) ÷ (ループ回数)
つまり、 1 * 1 * sumin / n
---------------------------------

円周率の場合とほとんど変わらないと思います。

このアルゴリズムを、お使いのBASICで記述して下さい。

そのBASICでの記述方法が分からないと言うのなら、
「その他(プログラミング)」の方が良いかも。

質問のソースはカテゴリ違いですが、
アルゴリズムに関する質問だと思いますので、
言語に依存しない部分で回答します。

f(x) = x*x の関数を、0~1の区間で積分ですね。

まず、y 軸の範囲を考えます。
グラフを書けば分かりやすいと思います。

f(0) = 0 から始まり、xが増加すれば f(x) も増加。
f(1) = 1 で終わりなので、y 軸の範囲は 0~1 とします。

---------------------------------
ループ回数 n の入力

カウント sumin を初期化

ループ開始(n 回ループ)

x に 0~1の乱数を...続きを読む

Qawkによる多数のファイルへのアクセス

ディレクトリに次のようなファイル名のファイルが多数あったとします。
(共通部分;英数字のみ)_(日付;20060409)
awkで、これらのファイルの全てにアクセスしてデータを取得、
処理を行わせたいのですが、どのようにすればよいでしょうか?

Aベストアンサー

>/tmp/fooにabc_1、abc_2、scriptファイルをおいて
>試しにやってみましたところ、
>./test.script: line 6: /tmp/foo: Is a directory
>mv: cannot overwrite non-directory `abc_1' with >directory `/tmp/foo'
>というエラーメッセージになってしまいます。

このshell scriptは/tmp/fooを作業用のファイルとして使います。ですので、/tmp/fooというdirがあると正常に動作しません。ファイルは/tmp/foo以外のdirにおいて/tmp/fooが無い状態で動作させてください。

>それと、4行目の
>awk < $i > /tmp/foo
>の部分を詳しく教えていただけないでしょうか。
>for i in abc_*という書き方からして、
>iは、abcファイルたちの添字ですよね?

違います。
for loopでは、ls abc_*で表示されるファイル、つまりabc_1、abc_2が順にiに代入されてループが実行されます。

>すると、この$は何を意味するのでしょうか?

iに代入されたものを参照するときは$iと書きます。

>また、awkは、基本的には
>「awk 処理 ファイル名」
>という順に記述すると思いますが、4~7行目は逆になっています。

for loopを展開して書くと、
awk < abc_1 > /tmp/foo
mv /tmp/foo abc_1
awk < abc_2 > /tmp/foo
mv /tmp/foo abc_2
となります。
awkの処理の記述は省略しました。
man bashして、変数の参照と、for loopについて読んでみて下さい。

>/tmp/fooにabc_1、abc_2、scriptファイルをおいて
>試しにやってみましたところ、
>./test.script: line 6: /tmp/foo: Is a directory
>mv: cannot overwrite non-directory `abc_1' with >directory `/tmp/foo'
>というエラーメッセージになってしまいます。

このshell scriptは/tmp/fooを作業用のファイルとして使います。ですので、/tmp/fooというdirがあると正常に動作しません。ファイルは/tmp/foo以外のdirにおいて/tmp/fooが無い状態で動作させてください。

>それと、4行目の
>awk < $...続きを読む

Q円周率について

円周率について
円周率は永遠につづくといいますね
でも
直径×円周率=円周なら
円周÷直径=円周率ですよね
じゃあ直径が1ならどうするんですか?
円周÷1=も永遠につづくんですか?
1に割れない数なんてあるんですか?
教えてください。

Aベストアンサー

「永遠に続く」ねぇ。
6÷2 だって、永遠に続くんですよ。
ただし、0 が。 6÷2=3.000…

この質問で、頭を整理するために必要なのは、
「1 で割れない」の「割れる」という言葉
の意味を確認することです。

普通、「割れる」ではなく「割りきれる」
と言いますか、その意味は、
「割り算の答えが整数になる」である場合と、
「割り算の答えを何回か 10 倍すると整数になる」
である場合があります。

文脈によって違いますから、
区別して理解することが必要でしょう。

どちらの場合も、整数÷1は、必ず「割れる」
のですが、
割られる数が整数でないときは、
1で「割れる」とは限りません。
割られる数が円周率の場合も、
その例のひとつです。

Q特定桁の検索、行抽出(Shell)

B Shellscriptで
特定桁を検索して、該当文字があった場合に
その行を抽出するにはどうすれば良いでしょうか?

例)3~5桁目をABCで検索する場合

00AAA0ABC ←ABCがあるが桁が違うので抽出しない
00AAB0AAA
00ABC0ABE ←この行を抽出する
00ABE0AAC

Aベストアンサー

awk/sed/grepなどのツールを使ってはいけないのでしょうか?

grep '^..ABC'

で、3~5桁目がABCの行だけ抜き出せますけど。


人気Q&Aランキング

おすすめ情報