pow関数を使わずに最速化する方法

このQ&Aのポイント
  • pow関数を使用せずに、プログラムの実行速度を向上させる方法を教えてください。
  • このプログラムは、pow関数を使用していて、実行速度が遅いです。pow関数を使わずに、もっと速く実行する方法を教えてください。
  • pow関数を使わずに、このプログラムを最速化する方法を教えてください。
回答を見る
  • ベストアンサー

最速化するにはどうしたらいいでしょうか?

#include <stdio.h> #include <math.h> #include <time.h> double abssucc(double x){ return x / (1 - pow(2,-53)); } double abspred(double x){ return x * (1 - pow(2,-53)); } double succ (double x){ if(abs(x) < pow(2,-1022)) return x + pow(2,-1074); if (x >= 0) return abssucc(x); else return abspred(x); } double pred(double x){ if(abs(x) < pow(2,-1022)) return x - pow(2,-1074); if (x >= 0) return abspred(x); else return abssucc(x); } int main(){ clock_t start, end; double r= 0; int i=0; start = clock(); for(i;i<1000000;i++){ r= succ(1); printf("%.50f\n",r); }end = clock(); printf("ループ100万回の時間: %f秒\n", (double)(end - start) / CLOCKS_PER_SEC); } このプログラムをpow関数使わないでもっと速く動かしたいのですが、やり方がわかりません。 教えて下さい!お願いします。

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

  • ベストアンサー
  • kmee
  • ベストアンサー率55% (1857/3366)
回答No.1

使う値が決まっているのだから、先に計算して変数に入れておく。 > #include <time.h> double pow_2_53 ; double pow_2_1022 ; double pow_2_1074 ; /* とでもしておいて */ > double abssucc(double x){ return x / (1 - pow_2_53); /* と使う */ > int main(){ pow_2_53 = pow(2,-53); pow_2_1022 = pow(2,-1022); pow_2_1074 = pow(2,-1074); /*とmainの最初の方で代入 */ ....って、2の-1074って、doubleの範囲外にならないですか? doubleは64ビットでIEEE754準拠だとアンダーフローになると思うのですが。

arsenal_4
質問者

お礼

ありがとうございます!これで試してみます。

その他の回答 (2)

  • kmee
  • ベストアンサー率55% (1857/3366)
回答No.3

あっと、見落してた。質問には直接関係ないけど > abs(x) このプログラムがC言語なら、int abs(int) です。 doubleに使うならfabsです。

arsenal_4
質問者

お礼

そうなんですか。無知ですみません><直してみます!

  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.2

nextafter とか nexttoward は?

arsenal_4
質問者

お礼

そうですね!それも一つの方法だと思うので、試してみます。

関連するQ&A

  • どこがおかしいのでしょうか?

    #include <stdio.h> #include <math.h> #include <time.h> double pow_2_53 ; double pow_2_1022 ; double pow_2_1074 ; double abssucc(double x){ return x / (1 - pow_2_53); } double abspred(double x){ return x * (1 - pow_2_53); } double succ (double x){ if(abs(x) < pow_2_1022) return x + pow_2_1074; if (x >= 0) return abssucc(x); else return abspred(x); } double pred(double x){ if(abs(x) < pow_2_1022) return x - pow_2_1074; if (x >= 0) return abspred(x); else return abssucc(x); } int main(){ pow_2_53 = pow(2,-53); pow_2_1022 = pow(2,-1022); pow_2_1074 = pow(2,-1074); clock_t start, end; double r= 0; int i=0; start = clock(); for(i;i<1000000;i++){ r= succ(1); printf("%.50f\n",r); }end = clock(); printf("ループ100万回の時間: %f秒\n", (double)(end - start) / CLOCKS_PER_SEC); } このプログラムを動かしたいのですが、動きません。どこがおかしいのでしょうか? 教えて下さい!

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

    このプログラムは表示された数値を逆に入力するプログラムです。 入力した値の正誤を表示します。結果に問わず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; }

  • 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; }

  • γ関数のプログラム(初心者です)

    以下のようにγ関数のプログラムを組みました。 とりあえず整数値を入力すれば、正しい値は返しているということがprintfの4で確認できました。 もとはfortranで組んだプログラムをCに置き換えました。 ですが、実際走らせてみると、4で値は確認できますがsegmentation faultが出てしまいます。 ですからサブルーチンファイル(ユーザー関数?)として利用できません。 何がいけないのでしょうか? 正しくyが帰ってくるようにどうなおしたらよいのか教えてください。 #include <stdio.h> #include <math.h> double gamma(double x) { double c[8],y,a,r,b,s; int i; a=1.; r=1.; c[1]=5.771916e-01; c[2]=9.882058e-01; c[3]=8.970569e-01; c[4]=9.182068e-01; c[5]=7.567040e-01; c[6]=4.821993e-01; c[7]=1.935278e-01; c[8]=3.586834e-02; printf("0 %f\n",x); while(1){ if(x>2.){ x=x-1.; a=a*x; printf("1 %f %f\n",x,a); } else if(x<1.){ a=a/x; x=x+1.; printf("2 %f %f\n",x,a); } else{ break; } } x=x-1.; for(i=1;i<8;i++){ b=(double)(i); s=(c[i]*((double)(pow(-1,b))) *((double)(pow(x,b)))); printf("3 %d %f\n",i,c[i]); r=r+s; } y=a*(r+(0.03586834*((double)(pow(-1,8)))*((double)(pow(x,8))))); printf("4 %f\n",y); return y; } main() { double x,y; printf("数字を入力してください。"); scanf("%lf",&x); printf("メインプログラム %lf\n",x); y=gamma(x); printf("%f\n",y); }

  • 値の渡し方?(初心者)

    以前質問したプログラムについて、新たに質問です。 メインプログラムと、関数プログラムを組みました。 関数の中では、print文を使うと計算は正しく行われていて、結果が正しいことが分かりました。 でうが、メイン文の出力では、どこにも出てこない変な値が出てきてしまいます。 値の渡し方がおかしいのでしょうか? 誰か、アドバイスをお願いします。 ***以下プログラムです。*** #include <stdio.h> #include <math.h> double gamma(double x) { double c[9],y,a,r,b,s,z; int i; a=1.; r=1.; c[1]=5.771916e-01; c[2]=9.882058e-01; c[3]=8.970569e-01; c[4]=9.182068e-01; c[5]=7.567040e-01; c[6]=4.821993e-01; c[7]=1.935278e-01; c[8]=3.586834e-02; printf("0 %f\n",x); while(1){ if(x>2.){ x=x-1.; a=a*x; printf("1 %f %f\n",x,a); } else if(x<1.){ a=a/x; x=x+1.; printf("2 %f %f\n",x,a); } else{ break; } } x=x-1.; for(i=1;i<9;i++){ b=(double)(i); s=(c[i]*((double)(pow(-1.,b)))*((double)(pow(x,b)))); printf("3 %d %f\n",i,c[i]); r=r+s; } y=a*r; printf("4 %lf\n",y); return y; } main() { double x,y; printf("数字を入力してください。"); scanf("%lf",&x); printf("メインプログラム x= %lf \n",x); y=gamma(x); printf("x= %f y= %f\n",x,y); }

  • コンパイルエラーです。

    #include <stdio.h> #include <time.h> int main() { float a = 1; float b = 1; clock_t start, end; for(a <= 9999; a++) for(b <= 99999; b++) printf("%fx%f=%f\n",a, b, a*b); end = clock(); printf("[4x4]\n####################\n%fs\n####################\n",(double)(end - start) / CLOCKS_PER_SEC); return 0; } エラーが起きるのですが、僕には、どこが間違っているのかわかりません。 教えてください。

  • プログラミングについての質問

    C言語において、区分求積法・台形公式・シンプソンの公式を行いたいのですがうまくいきません。 1/1+x*xを求めたいと思います。以下が途中まで作ったプログラムです。 #include <stdio.h> #define FROM 0.0 #define TO 1.0 double func(double x) { double out; out = 1.0 / ( 1.0 + x * x ); return (out); } double kubun(double start, double end, int num) { int i; double h, s; h = ( end - start ) / num; s = 0.0; for(i=0; i<num; i++) s += func( start + i * h + h / 2.0 ); return ( s * h ); } double daikei(double start,double end,int num) { int i; double h,s; h = ( end - start ) / num; s = 0.0; for(i=1; i<num-1; i++) s += func( i * h ); return ((start / 2.0 + s + end / 2.0) * h ); } double simpson(double start,double end,int num) { int i; double h,s; h = ( end - start ) / num; s = 0.0; for(i=1; i<num-1; i++) if(i%2 == 0){ s = 2 * func(i * h); }else{ s = 4 * func(i * h); } return ( (start + s + end) / 3 ); } 区分求積法はあったていると思いますが、不安なのでのせときます。 よろしくお願いします。

  • 乱数について

    プログラミングの授業で、各種ソートのプログラムを勉強しました。 srand (99);でランダムに数字を作っていると教わったのですが、この中の数字もランダムにしたい場合、どのようなプログラムに変えればいいのでしょうか? また、括弧内の数字で、どのようにランダムに数字をはき出しているのか知りたいです。 ~time.c~ #include <stdio.h> #include <stdlib.h> #include <time.h> #define MAX 250000 void insert_sort(int x[], int n); main() { int i , x[MAX] , n ; time_t start , end ; //列配列の選択 srand (99); for (i = 0 ; i<MAX ; i++) x[i] =rand() % MAX; n = MAX; start =clock(); //測定対象プログラム insert_sort (x ,n); end = clock(); printf("sort\n"); for(i =0 ; i < n ; i++ ) if ( i == i/100*100) printf("%d\n" , x[i]); printf ("%f sec\n" , (double)(end-start) /CLOCKS_PER_SEC); return 0; } ~insert.c~ void insert_sort(int x[], int n) { int i, j, tmp; for(i=1;i<n;i++){ for(j=i;j>0;j--){ if(x[j]<x[j-1]){ tmp = x[j]; x[j]=x[j-1]; x[j-1]=tmp; } else{ break; } } } }

  • ニュートン法

    ケプラー方程式x-e*sin(x)-c=0の解をステップ数とともに出力するプログラムで、e,cはそれぞれ0.5と1です。 xに値を入力して計算させるのですが、どうしてもできません。 下のプログラムリストでおかしいところはどこでしょうか? // ニュートン法 x-e*sin(x)-c=0 #include <stdio.h> #include <math.h> #define e 0.5 #define c 1.0 #define K 10000 double fun(double x); double bibun(int i,double x); float m=1.0,n=1.0; int i=1; main(){ float x1,x2; float z; printf("初期値x0を入力して下さい\n"); scanf("%f",&x1); for(i=0;i<=K;i++){ x2 = x1 - fun(x1)/bibun(i,x1); x1 = x2; z = fun(x1); z = fabs(z); if(fabs(z)<=0.00001){ break; } if(i==K){ printf("収束しません\n"); exit(0); }    } printf("解 = %f\n",x1); printf("ステップ数 = %d",i); return 0; } // 関数f(x) double fun(double x1){ double r; r = x1 - e * sin(x1) - c; return r; } // 微分 double bibun(int i,double x1){ float p; if(i%2==1){ p = pow((-1.0),m)*e*sin(x1); m++; } else { p = pow((-1.0),n)*e*cos(x1); n++; } return p; }

  • クイックソートの交換回数

    クイックソートを行うプログラムを書いています。 これを、比較回数と交換回数を表示できるように改良したいのですが、うまくいきません。カウントする場所は間違えてないと思うのですが、出力の場所が悪いせいか、大量の出力結果が表示されます。 うまく表示させる方法を教えてください。 ~time.c~ #include <stdio.h> #include <stdlib.h> #include <time.h> #include "sfmt.h" #define MAX 5000 void quick_sort(int a[], int start, int end); main() { int i , x[MAX] , n; time_t start , end ; int sn; printf("適当な数字の入力 : "); scanf("%d", sn); init_gen_rand(sn); for(i=0; i<MAX; i++) x[i]= (gen_rand32()% MAX);; n=MAX; start = clock(); //測定対象プログラム quick_sort(x, 0, n-1); end = clock(); printf("sort\n"); for(i =0 ; i < n ; i++ ) if ( i == i/100*100) printf("%d\n" , x[i]); printf ("実行時間: %f sec\n" , (double)(end-start) /CLOCKS_PER_SEC); return 0; } ~quick.c~ #include <stdio.h> int hikaku = 0, koukan = 0; int divide_array(int x[], int start, int end) { int i, j, tmp; i = start; j = end -1; while(1){ while(x[i] < x[end])i++; hikaku++; //比較カウント while(x[j] > x[end] && j>i)j--; hikaku++; //比較カウント if(i >= j) break; tmp = x[i]; x[i] = x[j]; x[j] = tmp; koukan++; //交換カウント i++; j--; } tmp = x[i]; x[i] = x[end]; x[end] = tmp; printf("比較回数: %d\n", hikaku); printf("交換回数: %d\n", koukan); return i; } ~quick2.c~ int divide_array(int x[], int start, int end); void quick_sort(int a[], int start, int end); void quick_sort(int a[], int start, int end) { int s; if(start >= end) return; s = divide_array(a, start, end); quick_sort(a, start, s-1); quick_sort(a, s+1, end); }

専門家に質問してみよう