• 締切済み

数当てゲームについて(べき乗のあらわし方)

#include<stdio.h> #include<time.h> #include<stdlib.h> int main(void) { int limit=0; int no1,no2,no3; /*当てさせる値*/ int num; /*入力する値*/ int max=15; srand(time(NULL)); no1=rand(); no2=rand(); if(no1>no2) { do{ no3=rand()%(no1+1); }while(no3<no2); } else if(no1<no2) { do{ no3 = rand()%(no2+1); }while(no3<no1); } if(no1>no2) { if(num<no2 || num>no1) { printf("%d以上%d以下の数字を入力してください。\n",no2,no1); } } else if(no1<no2) { if(num<no1 || num>no2) { printf("%d以上%d以下の数字を入力してください。\n",no1,no2); } } do{ printf("あと%d回入力できます。数字を入力してください。\n",max-limit); scanf("%d",&num); limit++; if(num>no3) { printf("大きいです。\n"); } else if(num<no3) { printf("小さいです。\n"); } }while(num!=no3 && limit<max); if(num==no3) { printf("正解です。"); printf("%d回で当たりました。",limit); } else { printf("残念ながら不正解です。正解は%dでした。",no3); } return 0; } このプログラムは制限回数以内でランダムで入力した値を 当てさせるものです。 当てさせる数であるランダム値の範囲としましては、ランダムで 二つの値を入力して「小さいランダム値以上大きいランダム値以下」 です。 そして、その範囲内で制限回数以内に当てさせるというものです。 ここで質問なのですが、「制限回数を2のべき乗以内とするにはどうすれば いいのかということです。」 たとえば、 ランダム値が2000と2004が入力されたとしたら、お互いの差は4であり 二分検索法の平均検索回数の式「log2n」というものを使うと2回とするのが 検索回数として妥当であると考えるからです。 当てさせる数が 8以内ならば3 16以内ならば4 32以内ならば5 という形で制限回数が増えていくようにしたいです。 2^n<max<2^(n+1) ^はべき乗をあらわします。 上記のような式ならば、制限回数がn+1になるようにです。 プログラムの中では、制限回数をmaxとしています。 ですが、上記のようなあらわし方がよくわからなかったので、 max=15と暫定的に定めてあるだけです。 長くなりましたが、よろしくお願いいたします。

みんなの回答

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

1ビットずつシフトして0になるまでカウントするのはどうでしょう for (max = 0, i = num; i; i >>= 1, max++);

rinnshan
質問者

補足

大変申し訳ないです。 C言語の初心者なもので、おっしゃっている文章や式の意味が よくわかりませんでした。(たとえば、for文の>>記号など) もしよろしければ、意味や組み込み方などを解説いただけると 大変うれしいです。

  • asuncion
  • ベストアンサー率33% (2127/6289)
回答No.2

2を底とする対数を求めるlog2関数は、標準関数にはないかもしれません。 どの処理系にも備わっているのは、  ・自然対数を求めるlog関数  ・常用対数を求めるlog10関数 だと思います。 また、aを底とするbの対数をlog(a)bと書くとき、次の公式が成り立ちます。 log(a)b = log(e)b / log(e)a  (eは自然対数の底) log(a)b = log(10)b / log(10)a 今回は、2を底とする対数を求めたいので、上記2つの公式のうちどちらかを使って、 log(2)b = log(e)b / log(e)2 あるいは log(2)b = log(10)b / log(10)2 として求めればよいです。

rinnshan
質問者

補足

ご回答ありがとうございます。 max=ceil(log(10)(abs(no1-no2)+1)/log(10)2); max=ceil(log(e)(abs(no1-no2)+1)/log(e)2); おっしゃるとおり、下の方がご回答してくださった 式と組み合わせて作ってみました。 ところが、両方とも 「関数でないものを呼び出している。」 「関数呼び出しに)がない」 と表示されてしまいました。 どうすればいいでしょうか?

  • qbr2
  • ベストアンサー率50% (62/123)
回答No.1

math.hにlog2関数がありますよ。 max=ceil(log2(abs(no1-no2)+1)); で、どうでしょうか? ここでの+1というのは、 ランダム値が2000と2004が入力されたとしたら、 お互いの差は4ですが、選択できる数字は 2000,2001,2002,2003,2004の5通りになるためです。

rinnshan
質問者

補足

回答ありがとうございます。 さっそくご指摘のとおり max=ceil(log2(abs(no1-no2)+1)); を加えてプログラムを組みなおしてみましたが、 log2がプロトタイプ宣言のない関数と表示されてしましました。 math.hはceilだけではないでしょうか?

関連するQ&A