• ベストアンサー

試行回数を多くするとなぜ動かないの?

お世話になっております、皆様のおかげでwindows上でCを動かせるようになりましたプログラマー猿のein_heldenlebenです。 Borlandの無償配布をインストールしてスペクトルのプログラム書いています。適当な乱数[srand(time(NULL)), rand()]を発生させてお決まりのモンテカルロ法でやってます。 正常にコンパイルできて、試行回数が少ないときは正常に動いてくれるのですが、試行回数を多くすると動かなくなります。たまーに最後まで動いて結果が出てくれたりします。非常に気まぐれです。 メモリーが解放されないなど私の知り得ないコンピューター内部で異常が起きてたりするのでしょうか?正常に働かせるにはどうしたらいいのでしょう? 環境はWindows XPあるいは2000です。何か思いつく対策を教えて下さい。

noname#3090
noname#3090

質問者が選んだベストアンサー

  • ベストアンサー
  • nitscape
  • ベストアンサー率30% (275/909)
回答No.1

これだけの情報ではさすがに原因までは分かりません。単に処理に時間がかかっているだけかもしれませんし、どこかで無限ルーチンに入り込んでいるのかもしれません。テキストファイルにログを書き出すようにしてみてそれを追ってみてはどうでしょうか?

noname#3090
質問者

お礼

zero divisionが発生するためだと言う事が分かりました。だから回数を多くするとダメになる事が多かったんです。プログラムミスですね。 回答ありがとうございました。

noname#3090
質問者

補足

ありがとうございます。 途中結果を打ち出すようにしてみれば止まる箇所が特定できるかもしれませんね。ちょっとやってみます。

その他の回答 (1)

  • terra5
  • ベストアンサー率34% (574/1662)
回答No.2

プログラムにバグがあるが、たまたま試行回数が少ないと 問題が発生しない、 回数が多くても常に発生するとは限らないということだろうと思います。 カウンタ等のオーバーフロー、バッファオーバーフロー、 初期化していない変数の使用、ポインタの使用ミス、 配列の添え字のオーバー、malloc等を使用していて未使用になっても開放していない、・・・あたりでしょうか。 プログラムをもう一度よくチェックしてください。 知りえない異常がおきるケースより、 単純なバグの可能性のほうがはるかに高いです。 あと、動かないというのは状況説明としては不十分ですね。 実行できない、実行すると***のエラーが出てとまる、 実行するといつまでも終わらない等、 正確に書かないと他の人にはわかりませんよ。 それぞれの場合でチェックする項目がかわってきますから。

noname#3090
質問者

お礼

回答ありがとうございました。

noname#3090
質問者

補足

失礼しました。エラーの表示も何も出ず、計算中のままでストップし、ctrl+Cを押して強制終了してやらねばならない状況に陥ってます。挙げて下さった項目を確かめてみます。

関連するQ&A

  • g++のrand

    VisualStudioで正常に動いていた乱数を用いたプログラムをLinuxのg++でコンパイルするとコンパイルはできるが正しい挙動をしないという問題に出くわしました。 調べていったところ、 float r = (float)rand() / (RAND_MAX+1); という処理のRAND_MAX+1がまずかったようです。 プリントして確認したら print(RAND_MAX) … 2147483647 print(RAND_MAX+1) … -2147483648 となっています。 オーバーフローしたためであろうということは検討がつくのですが、 理屈がはっきりわからず、すっきりしない感じです。 なぜ、RAND_MAXに+1をすると-2147483648になるのか(intが符号付だから??)、なぜwindows(Visual Studio)だと問題なかったのに、Linux(g++)だとダメなのか、 非常に初歩な質問かもしれませんが、どなたかご解説をお願いします。

  • C言語で乱数がうまく効きません。下記のソースでコンパイルして実行すると

    C言語で乱数がうまく効きません。下記のソースでコンパイルして実行すると結果が130固定となってしまいます。 #include <stdio.h> #include <stdlib.h> int main(void){ int x; x = rand(); printf("%d",x); return 0; } 使っているコンパイラはBorland C++ 5.5.1です。何か間違いでもあるのでしょうか?よろしくお願いします。

  • Borland C++ Compiler 5.5でland関数がコンパイルできません

    初歩的な質問ですみません。C言語のプログラミングの質問です。 タイトルどおり、Borland C++ Compiler 5.5でland関数がコンパイルできません。OSはWindows XPで、「c言語を始めよう!」を使ってプログラムを作っています。 今まで学校でunixを使っていたので、その時は何の設定もせずに使えたので普通に使ったのですが、”プロトタイプ宣言のない関数 'rand' の呼び出し”や”プロトタイプ宣言のない関数 'srand' の呼び出し”というエラーが出ます。 timeを使うために#include <time.h>が必要だったり、そのようなunixでは不必要だった下準備が必要なのでしょうか?

  • 初期化しているつもりなのに、初期化されずにrand関数の結果を得る

    皆様。こんにちは。 C++で簡単なプログラムを書いていたつもりでしたが、 コンパイルが正常であった後に、 プログラムを動作させてみたら、 自分の意図とは少し異なる結果となり、 どこが違うのか?が どうも自分では分かりかねてしまい、 アドバイスをいただきたく 質問させていただきました。 以下の例にあるように、 「a」と「b」という2文字の間に ランダム関数で作成した「任意の数字」を挟む処理を行い その結果を画面に表示するつもりです。 また、この処理を「num」で指定した回数分だけ 実行させたいと思っていました。 ■表示させようとした結果:「a」+「生成した乱数」+「b」 ■担当プログラム ------------------------------------------------------ for (int i=0; i<num; i++) { std::stringstream keystream ; srand((unsigned)time(NULL)); // 乱数の初期化 int randomnum = rand()% 109999999; // 乱数の生成 keystream << "a" << randomnum << "b" ;    printf(keystream); } ------------------------------------------------------ しかし、実際には、 指定された回数分だけの、 表示結果は得られるものの、 a123456b a123456b a123456b a123456b a123456b 上記例(num=5)のように、 乱数の部分が、全部同じ乱数となっていました。 しかし、forの中で 新たに乱数を生成する際、 生成する前に、 乱数の初期化をしているつもりでいますので、 プログラムを実行させた場合に、 表示させれた結果が、 どうして全て同じ乱数を得ているのか?が分からないでいます。 何かアドバイスいただけるとありがたいです。 宜しくお願い致します。

  • drand48()が使えない

    お世話になっております、皆様のおかげで昨日ウインドウズ上でCを動かせるようになったサルプログラマーです。 Borlandの無償配布をダウンロードしました。Linuxで gcc program1.c -o program1 -lm -O としてコンパイルできていたものをそのまま持ってきて(拡張子変えて)、 C:\bcc>bcc32 program1.cpp としたら Borland C++ 5.5.1 for Win32 Copyright (c) 1993, 2000 Borland program1.cpp: エラー E2268 program1.cpp 61: 未定義の関数 'srand48' を呼び出した(関数 main() ) エラー E2268 program1.cpp 66: 未定義の関数 'drand48' を呼び出した(関数 main() ) *** 2 errors in Compile *** となってしまいました。 いままでプログラムの中身は ======================================================== srand48(seed); for(i=0; i<I; i++){ while(1){ do{ x=drand48()*2.0-1.0; y=drand48()*2.0-1.0; : : ======================================================== という形でLinux上ではコンパイルできてましたが、ウインドウズに持ってきたらダメでした。ある掲示板でdrand48()は非標準関数であるとありましたが、このために使えないのでしょうか?[0,1)のdoubleの乱数を返す、また質がいいからオススメと友達に言われて使っていたのです。ですから非常にいいなあと思って使っていたのですが、どうにかならないでしょうか。使えるようにするにはどうしたらよいのでしょうか、色々あるかと思いますが何か解決方法をご教授ください。

  • PICマイコンによる乱数の表示について

    度々こちらで、お助け頂いております。 さて、今回の主旨はPICマイコンによりLCD表示器へ6個の数字を 表示する方法についてご質問させていただきました。 プログラミングはPIC用コンパイラCCS社のCコンパイラを使用し、 Micro chip社のMPLABと統合動作させています。 一般的なC言語と異なる部分があり、扱づらい面のあるコンパイラです。 では、問題のソースコードを次に記述します。 細部の設定や定義は省いて記述してあります。 1.void main() 2. { 3.int data,i; 4.srand((unsigned)time(ULL)); 5.data = 0; 6.表示器の初期化 7.カーソル位置をHomeへ 8.while(1) 9.{ 10.入力信号判定式 11.for(i = 0; i < 6; i++) 12. { 13. data=rand( )%6 + 1; 14. printf(lcd_data"%3d",data); 15. } 16.入力信号判定式 17.break; 18. } 19. } 以上、これだけのソースコードですが、コンパイルすると、 行番4コードがコンパイルエラーとなります。 (※英語のメッセージは読取れません。(勉強不足)) PICに関するrand( )とsrand( )関数について、いろいろと調べてみましたが、 それらに該当する項目が見当たりません。 そこで、行番4の部分をsrand(data);に変更したら、何とかコンパイル成功します。 それをPICに書込み、ターゲットに実装試験してみると、 100回乱数表示のうち、18回同じ組合せの数が出てしまいます。 どうも、srandの初期化が上手く出来てないみたいですが・・・ 何処が不具合となっているのでしょうか? また、同じソースコードをパソコンの標準Cで試してみると、 130回とも全てランダムに画面表示されます。 そこでどなた様か、PICに詳しい方のお知恵を拝借し、 ご指南頂けるなら、大変幸いに思います。 何卒宜しくお願い申し上げます。

  • extern指定子の使い方

    こんにちは。 現在WindowsVistaでCプログラミングを行っています。 独習Cという本に沿って勉強しているのですが、extern指定子の使い方の所でつまずきました。 まず、サンプルプログラムを参照し、以下のような2つのファイルを作成しました。 (必要なヘッダファイルは全てインクルードしています。) ●main.c ____________________________________________________________ extern int random; void func(void); void main(void) { int i; for(i=1; i<=10; i++){ func(); printf("発生した乱数 : %d\n", random); } } ____________________________________________________________ ●func.c ____________________________________________________________ int random; void func(void) { long ltime; long utime; /*まず、time()関数とsrand()関数を使って乱数列の初期値を 毎回変更できるようにする*/ ltime=time(NULL); utime=(unsigned int)ltime/2; srand(utime); //乱数を発生させてrandomに代入する random=rand(); } ____________________________________________________________ この2つのファイルをコンパイルし、実行した所同じ整数が10個表示されました。 異なる整数を10個表示したいのですが、どうすればよいかが分からず困っています。 何か分かる方がいらっしゃれば、アドバイスをお願い致します。

  • 数当てゲームを作っているのですが

    数当てゲームを作っているのですが 乱数を設定してその値よりも小さい値を入力したら「小さい」、 大きい値を入力したら「大きい」と表示して その値を入力したときは「正解」と表示するような数当てゲームを作っています。 一応コードは書けたのですが、コンパイル、実行がうまくいかないのです。 ご指摘お願いします。 以下コード /* 1~99の乱数を発生させる */ #include <stdio.h> #include <stdlib.h> #include <time.h> int main(void) { int i,random; // 乱数の種を植える,種に時間を使う srand((unsigned)time(NULL)); for(i=0; i<1; i++) { //乱数の発生 random = 1 + rand()%99; printf("%d\n",random); } printf("数当てゲームをはじめます。\nコンピュータが当たり数を用意しました。当たり数は1~99の間にあります。\n"); for(;;) { printf("あなたの予想は? > "); scanf("%d",&i); if(i>random) puts("大きい"); else puts("小さい"); break; } if(random - i = 0) printf("正解"); return (0); }

  • 初心者の作ったプログラムの問題点を指摘ください。

    下のように、0から9までの乱数の発生回数の標準偏差を求めるプログラムを組んでみたのですが、最後のシグマの演算が無視されてしまい、0.000000と出力されてしまいます。どこがいけないのでしょうか? #include<stdio.h> #include<time.h> #include<stdlib.h> #include<math.h> int main (void){ int N,i,j,r,a[10]={0,0,0,0,0,0,0,0,0,0}; double S=0; printf("How many trials?;"); scanf("%d",&N); srand((unsigned)time(NULL)); /*初期化*/ for(i=0;i<N;i=i+1) { r=(int)(rand()/(RAND_MAX +1.0)*10); /*乱数N個取得*/ a[r]=a[r]+1; } for(r=0;r<10;r=r+1){ printf("a[%d]=%d.\n",r,a[r]); S=1/10*(S+sqrt((a[r]-N/10)*(a[r]-N/10)));  /*演算(無視されてしまう・・・)*/ } printf("Sigma=%f",&S); return 0; }

  • 試行回数

    サイコロ一つを転がして1の目が出る確率が6分の1になることはわかっているのですが、実際に試行を重ねていって、信頼できる結果を得るにはいったいどの程度の試行回数が必要でしょうか?計算方法があれば教えてください。