• ベストアンサー

コードの最適化について質問です。以下の2つのコードにおいて、最適化が可能なポイントを教えていただけませんか?

*gccコンパイラを通します。 ///code1/// void filter_optimized(int width, int height, int numcol, int rw, int gw, int bw) { int x, y, z; for (z=0; z<numcol; z++) for (x=0; x<height; x++) for (y=0; y<width; y++) if (z==0) c[x][y][z] = bw*((bw*a[x][y][0]+gw*a[x][y][1]+rw*a[x][y][2])/(rw+gw+bw)); else if(z==1) c[x][y][z] = gw*((bw*a[x][y][0]+gw*a[x][y][1]+rw*a[x][y][2])/(rw+gw+bw)); else c[x][y][z] = rw*((bw*a[x][y][0]+gw*a[x][y][1]+rw*a[x][y][2])/(rw+gw+bw)); return; } ///code2/// void edge_optimized(int width, int height, int numcol) { int x, y, z; int tmp; for (y = 0; y < width; y++) for (x = 0; x < height; x++) for (z = 0; z < numcol; z++) b[x][y][z] = (a[x][y][0]+a[x][y][1]+a[x][y][2])/3; for (y = 0; y < width; y++) for (x = 0; x < height; x++) for (z = 0; z < numcol; z++) { tmp = computeGx(width, height, x, y, z, b); if (tmp < 0) tmp = -tmp; if (tmp > 255) tmp = 255; c[x][y][z] = tmp; tmp = computeGy(width, height, x, y, z, b); if (tmp < 0) tmp = -tmp; if (tmp + c[x][y][z] > 255) c[x][y][z] = 255; else c[x][y][z] += tmp; c[x][y][z] = 255 - c[x][y][z]; if ((x==0)||(y==0)||(x==height-1)||(y==width-1)) c[x][y][z] = 255; } return; }

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

  • ベストアンサー
  • titokani
  • ベストアンサー率19% (341/1726)
回答No.5

#4です。 ああ、そうですね。すみません。じゃあ、まずreturnが無駄です(^^; で、あとzのループが無駄。 for (x=0; x<height; x++) for (y=0; y<width; y++) c[x][y][0] = bw*((bw*a[x][y][0]+gw*a[x][y][1]+rw*a[x][y][2])/(rw+gw+bw)); c[x][y][1] = gw*((bw*a[x][y][0]+gw*a[x][y][1]+rw*a[x][y][2])/(rw+gw+bw)); c[x][y][2] = rw*((bw*a[x][y][0]+gw*a[x][y][1]+rw*a[x][y][2])/(rw+gw+bw)); でいいんじゃないかと。 それと、 bw/(rw+gw+bw) gw/(rw+gw+bw) rw/(rw+gw+bw) はループの外で計算しておける。 あと、この程度のことはコンパイラの最適化にまかせたほうがいいのだけれど、c[x][y]とa[x][y]もポインタに置き換えることができる。

その他の回答 (7)

  • 7o8
  • ベストアンサー率55% (5/9)
回答No.8

a[][][]とc[][][]の配列の定義がイマイチわかっていないのですが、 例えば、a[width][height][2]、c[width][height][2]で定義されていると 仮定し、最適化を検討した場合、私なら以下のようなコードにします。 多次元配列ですと、そのメモリ位置決めに都度計算が行われるかと 思うのでそれを避けるために1次元配列化することと、なるべく レジスタを使用するように考慮することですね。 ※偉そうに書いていて、コンパイルすらしていないので  そのまま動作するかどうかは不明です(^^;  多次元配列のメモリ上の並びもうろ覚えで書いているので怪しいですが、  実際にデバッグ等しながら調整できる範囲かと思いますので  実際にベンチマークしてみてください。 尚、ある配列の大きさの中の一部のみ計算するための関数であるなら この手は使えません... また、配列すべてを計算するのであれば、そもそも、height,numcolを引数にする必要がなく、 defineで指定してあげるほうがいいです。 ///code1/// void filter_optimized(int width, int height, int numcol, int rw, int gw, int bw) { register int a1,i; int t,bwx,gwx,rwx,cnt,*cp,*ap;       //コンパイル結果を見てap,cpもregister指定してみる cp=&c[0][0][0]; ap=&a[0][0][0]; cnt=height*width; //計算できるところは予め計算 t=rw+gw+bw; bwx=bw/t; gwx=gw/t; rwx=rw/t; for (i=0; i<cnt;) { a1=ap[i]*bw + ap[i+1]*gw + ap[i+2]*rw; cp[i++] = bwx * a1; cp[i++] = gwx * a1; cp[i++] = rwx * a1; } }

voltaire00
質問者

お礼

配列を一次元かする、レジスタを使用するというのは参考になりました。 特にレジスタというのは使ったことがなかったので、また調べて見たいと思います。ありがとうございました。

  • titokani
  • ベストアンサー率19% (341/1726)
回答No.7

例えばa,cの型が、 int a[100][100][3]; int c[100][100][3]; ならば、 int (*pax)[100][3]=a; int (*pcx)[100][3]=c; int w=bw+gw+rw; for( int x=0 ; x < 100 ; x++ ){ int (*pay)[3]=*pax++; int (*pcy)[3]=*pcx++; for( int y=0 ; y < 100 ; y++ ){ int *pa=*pay++; int *pc=*pcy++; int t=bw*pa[0]+gw*pa[1]+rw*pa[2]; pc[0]=bw*(t/w); pc[1]=gw*(t/w); pc[2]=rw*(t/w); } } という感じでしょうか。 ただ、このあたりはコンパイラの最適化にまかせたほうが、いいコードを出力する可能性があります。

voltaire00
質問者

お礼

お礼が遅くなりましたことをお詫び致します。 ポインタによる最適化、大変参考になりました。 実践してみたいと思います。ありがとうございました。

  • titokani
  • ベストアンサー率19% (341/1726)
回答No.6

#5です。訂正。 for (x=0; x<height; x++){ for (y=0; y<width; y++){ c[x][y][0] = bw*((bw*a[x][y][0]+gw*a[x][y][1]+rw*a[x][y][2])/(rw+gw+bw)); c[x][y][1] = gw*((bw*a[x][y][0]+gw*a[x][y][1]+rw*a[x][y][2])/(rw+gw+bw)); c[x][y][2] = rw*((bw*a[x][y][0]+gw*a[x][y][1]+rw*a[x][y][2])/(rw+gw+bw)); } } です。 インデントというより、ブラケットはつけたほうがいいと思う。 出力コードにも関係ないし。

voltaire00
質問者

お礼

詳細な回答をどうも有難うございました。とても参考になりました。 下の回答も兼ねてお礼させてください。 そうですね。可読性のためにもブラケットは付けた方がいいですよね。 以後気をつけたいと思います。 興味があるのですが、ご指摘のように多次元配列をポインタで扱うにはどのようにすればよいのでしょうか?1次元配列ならわかりやすいのですが。。。 自分で調べるのが一番なのでしょうが、お話に上がったので、もしお時間があれば解説していただけると大変ありがたいです。

  • titokani
  • ベストアンサー率19% (341/1726)
回答No.4

>///code1/// これだと、一行分計算しただけでreturnしちゃうけど、いいの?

voltaire00
質問者

補足

インデントされてないので分かりにくいかもしれませんが、if~elseの処理はネストループ内部で行われます。 {}を付けておくべきでした。申し訳ありません。

  • Trick--o--
  • ベストアンサー率20% (413/2034)
回答No.3

http://www.geocities.jp/nakamiya_town/ProC.html こんな感じに。 いつの話か知らんけどね

voltaire00
質問者

お礼

ありがとうございます。参考にしてみます。

  • php504
  • ベストアンサー率42% (926/2160)
回答No.2

コンパイラにおまかせではだめですか gcc -O3 とか

voltaire00
質問者

お礼

オプションは使わない方向です。 ループをなんとかしたいのですが。。。

回答No.1

最適化って言ってもいっぱいあるけど。 1.サイズ 2.速度 3.読みやすさ 1.と2.の場合、アセンブリで記述してみれば? レジスタの数によってだいぶ変わると思うよ。

voltaire00
質問者

お礼

なるほどアセンブリですか。苦手ですが試してみます。。。 ちなみに記述し忘れましたが、今回は最適化は速度向上を目指しています。

関連するQ&A

  • Javaの基礎のプログラム

    結城浩さんの本に載っていたプログラムです。 ですが、説明がわかりにくくていまいち処理がわからなかったので 質問させていただきました。 どうやら、X軸とY軸がありY軸は下に行けばいくほど数字が大きくなる。 X軸は右に行けばいくほど大きくなる。座標上にある、二つの長方形の重なりあう部分の座標を求めるプログラムのようです。(イメージとしては、下に添付してある画像のような感じになるようです。) 質問としては一つです。 プログラム中のこの部分なのですが、おそらく「長方形の座標を示している」行であると思います。 a = new Rectangle(0, 0, 20, 10); b = new Rectangle(5, 5, 20, 10); c = new Rectangle(20, 10, 20, 10); d = new Rectangle(-10, -20, 100, 200); e = new Rectangle(21, 11, 20, 10); その後の処理としては、aとb→c→d→eというようにそれぞれ比較していっているのもなんとなくわかります。 ですが、しっかり解説されていなかったので、この4つの数字がどのように座標を示しているのかよくわかりませんでした。 よろしくお願いします。 class Rectangle { final int INITIAL_WIDTH = 10; final int INITIAL_HEIGHT = 20; int width; int height; int x; int y; Rectangle() { width = INITIAL_WIDTH; height = INITIAL_HEIGHT; x = 0; y = 0; } Rectangle(int width, int height) { this.width = width; this.height = height; this.x = 0; this.y = 0; } Rectangle(int x, int y, int width, int height) { this.width = width; this.height = height; this.x = x; this.y = y; } void setLocation(int x, int y) { this.x = x; this.y = y; } void setSize(int width, int height) { this.width = width; this.height = height; } public String toString() { return "[" + x + ", " + y + ", " + width + ", " + height + "]"; } Rectangle intersect(Rectangle r) { int sx = Math.max(this.x, r.x); int sy = Math.max(this.y, r.y); int ex = Math.min(this.x + this.width, r.x + r.width); int ey = Math.min(this.y + this.height, r.y + r.height); int newwidth = ex - sx; int newheight = ey - sy; if (newwidth > 0 && newheight > 0) { return new Rectangle(sx, sy, newwidth, newheight); } else { return null; } } public static void main(String[] args) { Rectangle a, b, c, d, e; a = new Rectangle(0, 0, 20, 10); b = new Rectangle(5, 5, 20, 10); c = new Rectangle(20, 10, 20, 10); d = new Rectangle(-10, -20, 100, 200); e = new Rectangle(21, 11, 20, 10); System.out.println("a = " + a); System.out.println("b = " + b); System.out.println("c = " + c); System.out.println("d = " + d); System.out.println("e = " + e); System.out.println("a と a の重なり = " + a.intersect(a)); System.out.println("a と b の重なり = " + a.intersect(b)); System.out.println("a と c の重なり = " + a.intersect(c)); System.out.println("a と d の重なり = " + a.intersect(d)); System.out.println("a と e の重なり = " + a.intersect(e)); } }

    • ベストアンサー
    • Java
  • 配列の中身を入れ替える方法を教えてください

    配列の中身を入れ替える方法をどなたかおしえてください。下のプログラムはちゃんと実行されるんですが、いまいち納得できません。 特に・・・↓↓ void sort(int a[]) { int x,y,z,min; for(x=0;x<10;x++) { min=x; for(y=x;y<10;y++) { if(a[min]>a[y]) { min=y; } } z=a[min]; a[min]=a[x]; a[x]=z; } } 上の部分でなぜfor文を2回使うのか?2回目のfor文のところはなぜ y=xなのか?0ではいけないのか?よくわかりません。一番最後の入れ替え作業のところは納得できたんですが、for文のところがよくわからないのでどなたか分かる方教えてください! #include "stdafx.h" #include <stdio.h> #include <stdlib.h> #include <time.h> void sort(int a[]) { int x,y,z,min; for(x=0;x<10;x++) { min=x; for(y=x;y<10;y++) { if(a[min]>a[y]) { min=y; } } z=a[min]; a[min]=a[x]; a[x]=z; } } int main(int argc, char* argv[]) { int a[10],b,c; srand((unsigned)time(NULL)); for(b=0;b<10;b++) { a[b]=rand(); c=a[b]; printf("a[%d]=%d\n",b,a[b]); } sort(a); for(b=0;b<10;b++) { printf("小さい順a[%d]=%d\n",b,a[b]); } return 0; }

  • カメラを用いて動画から画像を取り込みトリミングしようとするプログラムを

    カメラを用いて動画から画像を取り込みトリミングしようとするプログラムを作っています. 最下部のプログラムを貼り付けているところまででデバックしつつ実行すると "OpenCVwithDShow.exe の 0x00462614 でハンドルされていない例外が発生しました: 0xC0000094: Integer division by zero" とエラー文がでてきます. 色々考えたのですが、原因が分からないのでどなたかご教授お願いします. よろしくお願いします. //トリミング CvRect cvClipRect(IplImage *frame, CvRect r) { r.x = 240; r.y = 0; r.width = 1080; r.height = 1680; if (r.x < 0) {r.width += r.x; r.x = 0;} if (r.y < 0) {r.height += r.y; r.y = 0;} if (r.x >= frame->width ) {r.width -= r.x - frame->width ; r.x = frame->width - 1;} if (r.y >= frame->height) {r.height -= r.y - frame->height; r.y = frame->height - 1;} if (r.width > frame->width - r.x) {r.width = frame->width - r.x;} if (r.height > frame->height - r.y) {r.height = frame->height - r.y;} return r; } IplImage *cvCreateSubRectImage(IplImage *frame, CvRect r) { IplImage tmp; CvMat submat; cvGetSubRect(frame, &submat, cvClipRect(frame, r)); cvGetImage(&submat, &tmp); return cvCloneImage(&tmp); } //トリミング終了 int main (int argc, char **argv){ CvCapture *capture = 0; IplImage *frame = NULL; IplImage *frame1 = NULL; IplImage *reduce = NULL; int c; int x,y; int max,min; int h,s; uchar p[3]; LabelingSS labeling; short *src_buf; float centerX,centerY; HANDLE hCom; //トリミング関数 // (1)コマンド引数によって指定された番号のカメラに対するキャプチャ構造体を作成する if (argc == 1 || (argc == 2 && strlen (argv[1]) == 1 && isdigit (argv[1][0]))) capture = cvCreateCameraCapture (argc == 2 ? argv[1][0] - '0' : 0); /* この設定は,利用するカメラに依存する */ // (2)キャプチャサイズを設定する. cvNamedWindow ("Capture", CV_WINDOW_AUTOSIZE); frame1 = cvQueryFrame (capture); src_buf = new short[ frame1->width * frame1->height ]; // (3)カメラから画像をキャプチャする while (1) { frame1 = cvQueryFrame (capture); frame = cvCloneImage(frame1); //トリミング呼び出し CvRect cvClipRect(IplImage *frame, CvRect r); IplImage *cvCreateSubRectImage(IplImage *frame, CvRect r);

  • 参照による呼び出し

    参照による呼び出しで3つの整数を大きい順に並び替えるという プログラムで、 #include<stdio.h> void change(int *x,int *y,int *z);/       main(){ int a,b,c; scanf("%d %d %d",&a,&b,&c); printf("入力データ:a=%d,b=%d,c=%d\n",a,b,c); change(&a,&b,&c); printf("入れ替え後:a=%d,b=%d,c=%d\n",a,b,c); return(0); } void change(int *x,int *y,int *z){ if(*x>*y){ *a=*x; *c=*y; } else{ *a=*y; *c=*x; } if(*z>*a){ *b=*a; *a=*z; } else if(*z>*c){ *b=*z; } else{ *b=*c; *c=*z; } } のように作ったのですが、zの値が一度も使われていないとエラーが 出てしまいます。どこをどう直せばいいか教えてください。 お願いします。

  • コンパイルエラーについて

    関数 y=x と y=x*x/8 のグラフをテキストで描くプログラムなのですが、cygwinでコンパイルすると次のエラーが出ます。何を直せばいいのか教えてください。 /tmp/cceveo7s.o:week2.c:(.text+0x62): undefined reference to `_f' /tmp/cceveo7s.o:week2.c:(.text+0xb1): undefined reference to `_f' /tmp/cceveo7s.o:week2.c:(.text+0xbd): undefined reference to `_g' collect2: ld はステータス 1 で終了しました ソースプログラムはこちらです。 #include <stdio.h> #define XSIZE 20 #define YSIZE 20 char graph[XSIZE][YSIZE]; /* 座標(x, y)に文字cをプロットする */ void f(int x, int y, char c); /* 作成したグラフを表示する */ void g(void); int main(void){ int x, y; for (x=0;x<XSIZE;x++){ y = x; f(x, y, '+'); } for (x=0 ; x < XSIZE ; x++){ y=x*x/8 ; f(x, y, '*'); if(y>=YSIZE) break; g(); return 0; } void f(int x, int y, char c) { graph[x][y] = c; } void g(void) { int a, b; for (b=YSIZE ; b>0 ; b--){ for (a = 0 ; a < XSIZE ; a++){ if (graph[a][b]==0) printf(" "); else printf("%c ", graph[a][b]); } printf("\n"); } } return 0; }

  • c言語

    c言語で写真の課題を出されたのですが自分のプログラムでは上手くいきません。どこが間違っているのか教えて欲しいです。 自分のプログラム #include<stdio.h> #include<math.h> int main(){ int i,j; double c,d,x,y,z; for(i=0;i<=360;i++){ c=10*cos(i*M_PI/180); d=10*sin(i*M_PI/180); if(c>=0 && d>=0){ for(j=0;j<=1000;j++){ x=0.001*j; y =x*d/c; z=1-x*x-(sqrt(x)+y)*(sqrt(x)+y); if(z<=0.0){break;} } } if(c<=0 && d>=0){ for(j=0;j<=1000;j++){ x=-0.001*j; y=x*d/c; z=1-x*x-(sqrt(-x)+y)*(sqrt(-x)+y); if(z<=0.0){break;} } } if(c<=0 && d<=0){ for(j=0;j<=1000;j++){ x=-0.001*j; y=x*d/c; z=1-x*x-(sqrt(-x)+y)*(sqrt(-x)+y); if(z<=0.0){break;} } } if(c>=0 && d<=0){ for(j=0;j<=1000;j++){ x=0.001*j; y=x*d/c; z=1-x*x-(sqrt(x)+y)*(sqrt(x)+y); if(z<=0.0){break;} } } printf("x=%lf y=%lf z=%lf\n",x,y,z); } return(0); }

  • C言語のプログラムについて質問

    明解C言語という書籍に 大きい方を表示するプログラム #include <stdio.h> int maxof(int x, int y) {  if (x > y)   return (x);  else   return (y); } int main(void) {  int na, nb;  puts("二つの整数を入力してください。");  printf("整数1:"); scanf("%d", &na);  printf("整数1:"); scanf("%d", &na);  printf("大きいほうの値は%dです。\n", maxof(na, nb));  return (0); } の関数maxofを利用し、 int max4(int w, int x, int y, int z) {  return (maxof(maxof(w, x), maxof(y, z))); } を挿入して変えれば四つの整数から最大値を求められるとのことですが、 コンパイルがうまくいきません。 関数maxofのwとx,yとzをそれぞれ比較し最大値を求めてさらにmaxof(w, x)とmaxof(y, z)を比較して最大値を求めるということですよね?ですので、 maxof(w, x) {  if (w > x)   return (w);  else   return (x); } maxof(y, z) {  if(y > z)   return (y);  else   return (z); を挿入しようとしたらmaxofはすでにありますというようなことが表示されてだめでした。 また、 int maxof(maxof(int w, int x), maxof(int y, int z)) { if (w > x)   return (w); if (w < x)   return (x); if (y > z)   return (y); if (y < z)   return (z); if (maxof(w, x) > maxof(y, z))   return (maxof(w, x)); if (maxof(w, x) < maxof(y, z))   return (maxof(y, z)); } としてみましたがやはりだめでした。 前のページの説明を読み返したりネットで調べてもわかりませんでした。 何がわからないのかがわからないのでもうお手上げです。 長くなってすいません プログラム例と説明をお願いします。

  • カラー画像からグレースケール画像フォーマットの変換

    カラー画像からグレースケール画像フォーマットの変換するプログラムなんですが、いまいち理解できていません。 プログラムはRGB構造体を使ってのものなんですが添削お願いいたします。 #include<stdio.h> #include<stdlib.h> typedef struct _RGB { unsigned char r; unsigned char g; unsigned char b; } RGB; int main(int argc, char *argv[]) { int x, y; unsigned char *in, *out; int i, j, Magic, level; unsigned char tmp[255]; RGB **pixels; int width = 255; int height = 255; int size = width * height; FILE *fin, *fout; if(argc != 3){ printf("Usage : %s input outpu \n", argv[0]); exit(1); } fin = fopen(argv[1], "rb"); fgets(tmp, 255, fin); if(tmp[0] != 'P'){ return 0; } sscanf(tmp, "P%d", &Magic); if(Magic < 1 || Magic > 6){ return 0; } do{ fgets(tmp, 255, fin); } while(tmp[0] == '#'); sscanf(tmp, "%d %d", &x, &y); if(x < 1 || y < 1){ return 0; } fgets(tmp, 255, fin); sscanf(tmp, "%d", &level); printf("P%d\n", &Magic); printf("%d %d\n", x, y); printf("%d\n", level); in = (unsigned char *)malloc(sizeof(unsigned char) *x*y); fread(in, sizeof(unsigned char), x*y, fin); pixels = (RGB**)malloc(width*sizeof(RGB*)); pixels[0] = (RGB* )malloc(size * sizeof(RGB)); for(i = 1; i < width; i++){ pixels[i] = pixels[i - 1] + height; } free(pixels[0]); for(i = 1; i < width * height * 3; i++){ out[i] = pixels[i][0].r * 0.299 + pixels[i][1].g * 0.587 + pixels[i][2].b * 0.114; } fout = fopen(argv[2], "wb"); fprintf(fout,"P%d\n",Magic); fprintf(fout,"# My new PGM\n"); fprintf(fout,"%d %d\n",x, y); fprintf(fout,"%d\n",level); fwrite(out, sizeof(unsigned char),x*y, fout); free(pixels); free(in); free(out); free(fin); free(fout); }

  • 四角形の当たり判定についての質問です。

    四角い2つブロックの当たり判定をとりたいです。1つのブロックは十字キーによって移動することができ、もうひとつのブロックは画面中央に固定されたまま動くことはありません。2つの四角形が当たった時に擦りぬけないようにしたいのですが、ぶつかったときに十字キーで上下左右に動かしてもすりぬけないようにしたのですが、斜めに移動させるとおかしくなってしまいます。次のプログラムをどう修正すればいいでしょうか? 変数の説明 Player.x:動く四角形のX座標 Player.y:動く四角形のY座標 Player.width:動く四角形の幅 Player.height:動く四角形の高さ Wall.x:動く四角形のX座標 Wall.y:動く四角形のY座標 Wall.width:動く四角形の幅 Wall.height:動く四角形の高さ //2つの四角形がぶつかっていなかったら if(!(((Player.x > Wall.x && Player.x < Wall.x + Wall.width) || (Wall.x > Player.x && Wall.x < Player.x + Player.width)) && ((Player.y > Wall.y && Player.y < Wall.y + Wall.height) || (Wall.y > Player.y && Wall.y < Player.y + Player.height)))) { //右キーを押していたら if(g_keyState[DIK_RIGHT] & 0x80 ) { Player.x += 3; if((((Player.x > Wall.x && Player.x < Wall.x + Wall.width) || (Wall.x > Player.x && Wall.x < Player.x + Player.width)) && ((Player.y > Wall.y && Player.y < Wall.y + Wall.height) || (Wall.y > Player.y && Wall.y < Player.y + Player.height)))) Player.x = Wall.x - Player.width - 1; } //左キーを押していたら if(g_keyState[DIK_LEFT] & 0x80) { Player.x -= 3; if((((Player.x > Wall.x && Player.x < Wall.x + Wall.width) || (Wall.x > Player.x && Wall.x < Player.x + Player.width)) && ((Player.y > Wall.y && Player.y < Wall.y + Wall.height) || (Wall.y > Player.y && Wall.y < Player.y + Player.height)))) Player.x = Wall.x + Wall.width + 1; } //上キーを押していたら if(g_keyState[DIK_UP] & 0x80) { Player.y -= 3; if((((Player.x > Wall.x && Player.x < Wall.x + Wall.width) || (Wall.x > Player.x && Wall.x < Player.x + Player.width)) && ((Player.y > Wall.y && Player.y < Wall.y + Wall.height) || (Wall.y > Player.y && Wall.y < Player.y + Player.height)))) Player.y = Wall.y + Wall.height + 1; } //下キーを押していたら if(g_keyState[DIK_DOWN] & 0x80) { Player.y += 3; if((((Player.x > Wall.x && Player.x < Wall.x + Wall.width) || (Wall.x > Player.x && Wall.x < Player.x + Player.width)) && ((Player.y > Wall.y && Player.y < Wall.y + Wall.height) || (Wall.y > Player.y && Wall.y < Player.y + Player.height)))) Player.y = Wall.y - Player.height - 1; } }

  • VBA と JIS Full BASIC

     下のJIS Full Basic スタイルとだいたい同じようなコードを VBA で書いたのですが   Z = Sqr(x^2 + y^2) のところでエラーが出ます。どこがおかしいのでしょうか。 Function gcd(a, b)   Do While b <> 0    r = a Mod b    a = b    b = r   Loop   gcd = a End Function Rem 既約なピタゴラス数を求める Sub Pythagoras()  LAST = 200   LAST = 200   For x = 1 To LAST    For y = x + 1 To LAST      Z = Sqr(x^2 + y^2)      'ここでコンパイルエラーが出る      If Int(Z) = Z Then       If gcd(x, y) = 1 And gcd(x, z) = 1 And gcd(y, z) = 1 Then         Debug.Print x & ", " & y & ", " & z       End If      End If    Next y   Next x End Sub ---------------------------- JIS Full Basic スタイルのコード REM ピタゴラス数 FUNCTION gcd(a,b)   DO WHILE b <> 0    LET r = MOD(a,b)    LET a = b    LET b = r   LOOP   LET gcd = a END FUNCTION LET LAST = 200 FOR x = 1 TO LAST   FOR y = x + 1 TO LAST    LET z = SQR(x^2+y^2)    IF INT(z) = z THEN      IF gcd(x,y) = 1 AND gcd(x,z) = 1 AND gcd(y,z) = 1 THEN       PRINT x,y,z      END IF    END IF   NEXT y NEXT x END

専門家に質問してみよう