• 締切済み

C+のsqrt

icpcの過去問(http://www.deqnotes.net/acmicpc/3006/ja)で、答えを #include <cmath> #include <iostream> using namespace std; #define max 1000000 int main(){ //int max = 100; int a,d,n,number[1000010]; for(int i=0;i<max;i++){ number[i] = 1; } number[0]=0;number[1]=0; for(int i=2;i<=sqrt(max)+1;i++){ if(number[i]){ for(int j=i*2;j<max;j=j+i){ number[j] = 0; } } } while(cin >> a >> d >>n,a||d||n){ int count =0; for(int i=a;i<=max;i=i+d){ if(number[i]){count ++; if(count == n){cout << i << endl;break;} } } } } と書いたところ、PKUで Main.cpp F:\temp\11386803.6056\Main.cpp(15) : error C2668: 'sqrt' : ambiguous call to overloaded function math.h(581): could be 'long double sqrt(long double)' math.h(533): or 'float sqrt(float)' math.h(128): or 'double sqrt(double)' while trying to match the argument list '(int)' F:\temp\11386803.6056\Main.cpp(16) : error C2108: subscript is not of integral type というコンパイルエラーがでます。 sqrtの前後で型が違っているのは分かるのですが、具体的にどうなおせばよいかわかりません。

みんなの回答

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

オーバーロードのしくみ、理解していますか? (1) sqrt(int)と定義されているものが無い (2) long double sqrt(long double),float sqrt(float),double sqrt(double) の3つのsqrtが該当しそうだけれど、いずれもintからの暗黙の型変換が可能なので、どれにすればいいかわからない というのがエラーの理由です。メッセージにもちゃんと書いてあります。 それならば、そのエラーとなる原因に対して、対応すればいいのです。 (1) からの解決策 intを引数に取り、その平方根をintで返す int sqrt(int) 関数を定義する。 (2) からの解決策 暗黙の型変換が曖昧なのあから、明示的に型変換する (3) 別の解決策 sqrtを使わないアルゴリズムを考える > int a,d,n,number[1000010]; せっかくmaxを定義してるのに、なんで1000010なんて値を直接書いてるのですか? それとも、この1000010という値はmaxとは無関係ななにかですか?

bcbcbc
質問者

お礼

ありがとうございました!

回答No.1

sqrtの引数の型をdoubleに変えるために、 for ( int i=2; i<=sqrt((double)max)+1; i++ ) でエラーは解消できますが、sqrtを使わないで for ( int i=2; i*i<=max; i=i+1 ) とした方が、整数の演算だけになるので打切り誤差の心配(1を加えて保険をかけている)をしなくて済みます。 ついでに、内側のforループは for ( int j=i*i; j<max; j=j+i ) にする方が演算回数が少なくなります。

bcbcbc
質問者

お礼

ありがとうございました!