• ベストアンサー

clock()関数の誤差

プログラムの実行時間の計測について質問させていただきます。 現在,実行時間の計測でclock()関数を使っているのですが誤差が出ます。 timeコマンド(と実際に時計で測った時間)では95分、clock()関数で測った プログラム全体の実行時間は1376秒(約23分)と誤差が出る状態にあります。 プログラムでclock()関数を使っているのはmain()だけです。 printf()内がおかしいのでしょうか? 詳しい方、回答よろしくおねがいします。 ↓プログラム #include<time.h> (中略) clock_t t1,t2,t3,t4; (中略) main() { struct zahyo P,Q; int a,b,prime,Ord,sec; scanf("%d",&a); (中略) printf("Q.y = "); scanf("%d",&Q.y); t1=clock(); Ord=OrdCal(P,a,prime); t2=clock(); printf("Ord = %d\n",Ord); printf("OrdCal:%f(s)\n",(double)(t2-t1)/CLOCKS_PER_SEC); t3=clock(); PohlingBsgs(P,Q,a,prime,Ord); sec=secretkey(); t4=clock(); printf("secretkey=%d\n",sec); printf("Decipher:%f(s)\n",(double)(t4-t3)/CLOCKS_PER_SEC); printf("Total :%f(s)\n",(double)(t4-t1)/CLOCKS_PER_SEC); } 実行結果 Ordcal:74.170000(s) Decipher:1302.722704(s) Total :1376.902104(s) real 94m33.445s user 94m30.900s sys 0m0.980s

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

  • ベストアンサー
  • redasurc
  • ベストアンサー率37% (3/8)
回答No.3

> time.hの関数を見たところ時間が測れるもので大きい数に対応している > ようなものはないように思えます。小刻みに時間を測るのでしょうか? > 何か良い方法はありますか?よろしかったら教えてください。 例えば、time() 関数と difftime()関数を使用すれば精度が秒ですが、長い時間をはかることができます。 clock()関数を使用するなら、やっぱり小刻みに時間をとっていくのが一番簡単かもしれません。

参考URL:
http://www.bohyoh.com/CandCPP/C/Library/time.html,http://www.bohyoh.com/CandCPP/C/Library/difftime.html
ume-kun
質問者

お礼

time() 関数とdifftime()関数ですね。やってみます。 分かるまで教えていただいてありがとうございました!

その他の回答 (2)

  • redasurc
  • ベストアンサー率37% (3/8)
回答No.2

t1~t4の変数がオーバーフローしているのではないでしょうか? CLOCKS_PER_SEC=100,000として、オーバーフローしていると考えると、Totalの本来の時間は (t4-t1) の 1376902104 に 2^32=4294967296 を加えた時間になります。 これは 5671869400 となり、CLOCKS_PER_SECで割ると約5,672秒(約95分)となりますね。

ume-kun
質問者

補足

回答していただいてありがとうございます。 2^31でオーバーフローしていました。ということは90分を超えたりする とclock()は使えないですよね。 time.hの関数を見たところ時間が測れるもので大きい数に対応している ようなものはないように思えます。小刻みに時間を測るのでしょうか? 何か良い方法はありますか?よろしかったら教えてください。

  • jacta
  • ベストアンサー率26% (845/3158)
回答No.1

clock関数というのは、その処理系での最良の近似を返すことだけが規定されており、分解能や精度などに関しては一般的には何も保証されません。ですから、常に123という値が返ってきたとしても、性能面はともかく、規格上の機能要件は満たしていることになります。また、プロセッサ時間が無効か表現不能の場合には(clock_t)-1を返します。 特定の処理系に関する情報が欲しいのであれば、まずはその処理系のマニュアルを熟読してください。それでもわからなければユーザーサポートを利用するか、最低限、対象となる処理系を特定した上で再質問してください。

ume-kun
質問者

お礼

回答していただいてありがとうございました!

関連するQ&A

  • clock関数は正確じゃないの?

    clock関数で時間を計測するとどうも狂ってしまいます。 おかしいので、このようなプログラムでclock関数の精度を調べてみました。 #include <stdio.h> #include <time.h> int main(){     int i,j;     clock_t start;     for(i=0;i<50;i++){         start = clock();         for(j=0;j<3000000000;j++);         printf("%4.3f秒\n",(double)(clock()-start)/CLOCKS_PER_SEC);         }     return 0; } このプログラムの実行結果はこちらです。 1.672秒 1.672秒 1.672秒 1.672秒 1.687秒←● 1.672秒 1.672秒 1.672秒 1.672秒 1.672秒 1.671秒 1.672秒 1.672秒 1.672秒 1.688秒←● ・・(略) 若干1.672で落ち着いているかと思いきや、時々狂っています。 この狂いは何が原因なんでしょうか? しかも狂うときは0.01位、結構ガツンと狂います。 しかもその狂い←●が等間隔で現れるのかと思いきや、そうでもありません。 この一見そろっているようで、時々ガツンと狂うのは何故なんでしょうか?

  • clock関数での経過時間計測

    clock関数でプログラムの時間を計測しようと思っているのですがうまくいきません。 ----------------------------- clock_t start,end; start = clock(); (処理) end = clock(); printf("かかった時間:%f",(double)(end-start)/CLOCKS_PER_SEC); ----------------------------- 上のようにしているのですが、実行結果は0.00000秒と出てしまいます。処理のところは足し算を何題か出題し解答を入力し正解したら次の問題というようなことをしています。 確認のためstartにclock()を代入した後とendに代入したあとでprintfでstartとendを出力してみましたが、どちらの値も10.00000で同じ値となっています。0秒になるのはこれのせいだと思うのですが、どうして同じ値になるのでしょうか?

  • clock関数を利用した時間計測法について

    以下のソースコードについての質問です。 --- /* 文字列を1文字ずつ表示して後ろから1文字ずつ消去するのを繰り返す */ #include <time.h> #include <stdio.h> /*--- xミリ秒経過するのを待つ ---*/ int sleep(unsigned long x) { clock_t c1 = clock(), c2; do { if ((c2 = clock()) == (clock_t)-1) /* エラー */ return (0); } while (1000.0 * (c2 - c1) / CLOCKS_PER_SEC < x); return (1); } --- このコード中の while (1000.0 * (c2 - c1) / CLOCKS_PER_SEC < x); の箇所で、整数の 1000 ではなく、実数の 1000.0 を使う意味(メリット)は オーバーフロー対策の他に何かありますか? ありましたら教えてください。 また、整数の1000に比べ実数の1000.0を含む計算(浮動小数点演算)に 極端に時間がかかる環境の場合、 実数を使う方がsleep関数の精度が劣るデメリットがあると思いますが、 その他に実数を使う場合のデメリットはありますか? ありましたら教えてください。 (コードにおいて、clock_t型はunsignedと同義の場合もあれば signed long intと同義の場合もあると思いますが、どれもありうる(処理系依存)と考えてください。 CLOCKS_PER_SECも1000や1000000の場合もあると思いますが、どれもありうる(処理系依存)と考えてください。)

  • 秒数を数える(C言語)

    プログラム実行時に時間を数え始めて、100秒経過したらまた最初からプログラムを実行しようと考えています。(tcpdumpみたいなもの) まず、秒数を数えて出力するプログラムを作ってみたのですが、実行しても0.000000と出てしまい、数えることが出来ませんでした。 (例) #include<stdio.h> #include<time.h> void tekitou(); int main() { while(1) { /*無限ループ*/ tekitou(); } return 0; } void tekitou() { static time_t start; time_t last; start = clock(); last = clock(); printf("%f\n", (double)(last - start)/CLOCKS_PER_SEC); } OSはLinuxでコンパイラはgccです。よろしくおねがいします。

  • 4桁の英字の3桁目を当てるプログラム

    乱数でとってくる4ケタの英字の3桁目を入力して当てるプログラムを 組もうとしているのですが、コンパイラしてもいまいちうまくいきません。 特に下に書いたプログラムのこの部分が違っていると思い どのように修正したらよいのか指摘していただきたいです。 human=getchar(); if(comp[2]!=human) { ero=1; } よろしくお願いします。 #include<stdio.h> #include<stdlib.h> #include<time.h> #include<string.h> int sleep(unsigned long x) { clock_t c1=clock(),c2; do{ if((c2=clock())==(clock_t)-1) { return 0; } }while(1000.0*(c2-c1)/CLOCKS_PER_SEC<x); return 1; } int main(void) { int num,val,i,j; char comp[21]; char human; int ero=0; int try_count=0; int seikai=0; clock_t start,end; int num1; char eiji[]="ABCDEFGHIJKLMNOPQRSTUVWXYZ"; srand(time(NULL)); puts("英字記憶トレーニング"); do{ printf("挑戦するレベル(3~20):"); scanf("%d",&num1); }while(num1<3 || num1>20); printf("%d個の英字を記録しましょう。\n",num1); start=clock(); do{ for(i=0;i<num1;i++) { comp[i]=eiji[rand()%strlen(eiji)]; } comp[num1]='\0'; printf("%s",comp); fflush(stdout); sleep(125*num1); printf("\r%*s\r3番目の英字を入力してください:",num1,""); human=getchar(); if(comp[2]!=human) { ero=1; } if(ero==0) { printf("正解です。\n"); seikai++; } else { printf("\a間違いです。\n"); } try_count++; }while(try_count<2); end=clock(); printf("%d回中%d回成功しました。\n",try_count,seikai); printf("%.1f秒でした。\n",(double)(end-start)/CLOCKS_PER_SEC); return 0; }

  • 時間を経過させる関数

    この関数は引数xに1000を渡すと1秒の経過をさせる 関数です。 int sleep(unsigned long x) { clock_t c1 = clock(),c2; do { if((c2 = clock()) == (clock_t)-1) return 0; }while(1000.0*(c2-c1)/CLOCKS_PER_SEC<x); return 1; } 質問は3つです。 (1) if((c2 = clock()) == (clock_t)-1) return 0; ・clock()を呼び出し、その結果をc2に代入する。c2が-1だったら、returnする。返却値は0を返す。 つまり、時間の経過中にエラーが起きたら値を返すというものです。 質問としては、「(clock_t)-1」の意味です。「clock_t型から-1を引く?」なぜ-1と等しいのでしょうか? (2) while(1000.0*(c2-c1)/CLOCKS_PER_SEC<x); この文なのですが、なぜc2からc1を引く理由としては ・c1は関数を呼び出した時点の時間であり0秒固定。 ・c2に関しては「上記の不等式が不成立になるまで経過する時間」 と考えてよろしかったでしょうか? (3) また、上記の文の不等式の右辺のxは単位がミリ秒なので、不成立になるには、不等 式の左側は「関数呼び出しから現在までの経過時間(ミリ秒)」になるはずです。 左辺は最初に(c2-c1)を1000倍をしてそこからCLOCKS_PER_SECという 一秒あたりのクロック数(1000)を割っているのでc2やc1は最初から ミリ秒の単位がclock()で渡されるということなのでしょうか? お手数ですがよろしくお願いします。

  • 一定周期実行プログラム

    UNIX環境での、プログラムを一定周期実行させるプログラミング方法についてご教授下さい。 例えば、50msの周期で、無限ループするプログラムです。 while(1) { t1=clock(); (処理1); t2=clock(); passtime=(t2-t1)/CLOCKS_PER_SEC; time=0.05-passtime; tmp=(int)(1000000*time); usleep(tmp); } まず、思い付いたプログラムは、処理1に掛かった時間を計算し、50msから処理に掛かった時間を引いた時間をsleepで待たせるプログラムです。clock()は精度が低いようですが・・・他に何かいい方法はないでしょうか?

  • 素因数分解のプログラムを作成しました。

    素因数分解のプログラムを作成しました。 なぜか11桁を超えた場合、正しく表示されません!! アドバイス等お願いします。 あと、処理時間も組んでみましたがこちらもうまくいきません。 改善をお願いしますm(_ _)m #include<stdio.h> #include<time.h> void fanction(int); void main(void) { int n; clock_t start_time, end_time; printf("整数を入力してください。\n"); scanf("%d",&n); start_time = clock(); fanction(n); end_time = clock(); printf("\n\n処理時間:%.3f秒\n",(double)(end_time - start_time) / CLOCKS_PER_SEC); return 0; } void fanction(int n) { int m; char c='='; for(m=2;n != 1;m++) { while(n%m == 0) { n = n/m; printf("%c%d",c,m); c='*'; } } }

  • それぞれの暗算にかかった時間

    このプログラムは3つの数字の和を暗算させるプログラムです。 プログラムでは、10回の暗算にかかった合計時間を表示させて います。 質問としては「それぞれの回数にかかった時間をそれぞれ 表示させるにはどうすればいいのかか?」です。 #include<stdio.h> #include<time.h> #include<stdlib.h> int main(void) { int a,b,c,i,n; int num; clock_t start,end; srand(time(NULL)); printf("暗算トレーニング開始!!\n"); start=clock(); for(i=0;i<10;i++) { a=10+rand()%90; b=10+rand()%90; c=10+rand()%90; n=rand()%17; printf("%d%*s+%*s%d%*s+%*s%d:",a,n,"",n,"",b,n,"",n,"",c); do{ scanf("%d",&num); if(num==a+b+c) { break; } printf("\a違います。再入力してください。\n"); }while(1); } end=clock(); printf("%.1f秒かかりました。\n",(double)(end-start)/CLOCKS_PER_SEC); return 0; }

  • ループが変な動作をする

    このプログラムは表示された数値を逆に入力するプログラムです。 入力した値の正誤を表示します。結果に問わず3回で終了する ようにしたいです。 ところが、下のプログラムを動作させたところ間違いを3回入力 したら終了するという仕様になってしまっています。 何がおかしいのでしょうか? for(m=0;m<3;m++) { ---------------------------------------(省略) if(strcmp(gyakuho,nyuu)!=0) { printf("\a間違いです。\n"); } else { printf("正解です。\n"); count++; } } おそらく、間違っているのはループの中のこの部分なのでは ないかと思います。 #include<stdio.h> #include<time.h> #include<stdlib.h> #include<string.h> int sleep(unsigned long x) { clock_t c1=clock(),c2; do{ if((c2=clock())==(clock_t)-1) { return -1; } }while(1000.0*(c2-c1)/CLOCKS_PER_SEC<x); return 0; } int main(void) { char gyaku[4]; char gyakuho[4]; int i,j,m; char nyuu[4]; int k=0; int count=0; clock_t start,end; char x; srand(time(NULL)); printf("4桁の数値を記憶しましょう。\n"); start=clock(); for(m=0;m<3;m++) { x='1'+rand()%9; gyaku[0]=x; for(i=1;i<4;i++) { do{ x='0'+rand()%10; for(j=0;j<i;j++) { if(x==gyaku[j]) { break; } } }while(j<i); gyaku[i]=x; } gyaku[4]='\0'; printf("%s",gyaku); fflush(stdout); sleep(500); printf("\r \n"); for(i=3;i>=0;i--) { gyakuho[k++]=gyaku[i]; } gyakuho[4]='\0'; printf("表示された数字を逆に入力せよ:"); scanf("%s",nyuu); if(strcmp(gyakuho,nyuu)!=0) { printf("\a間違いです。\n"); } else { printf("正解です。\n"); count++; } k=0; } end=clock(); printf("3回中%d回成功しました。\n",count); printf("%.1f秒でした。\n",(double)(end-start)/CLOCKS_PER_SEC); return 0; }

専門家に質問してみよう