error C2668

First of all, I'd like to mention that I was going to post a reply and revive an older thread with this exact subject matter, but it was closed. I'm working out of Brian Overland's book, and I'm entering his exact code for a Prime Number example into VS 2010. Here's the code:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
 
#include <iostream>
#include <cmath>
using namespace std;

int main() {
	int i;
	int n;
	int is_prime = true;
	cout << "Enter a number: ";
	cin >> n;

	i = 2;
	while (i <= sqrt(n)) {
		if (n % i == 0)
			is_prime = false;
		i++;
	}

	if (is_prime)
		cout << "Number is prime" << endl;
	else 
		cout << "Number is not prime" << endl;

	return 0;
}


After this code is entered and compiled, I receive the following errors:

1
2
3
4
5
error C2668: 'sqrt' : ambiguous call to overloaded function
1>          d:\program files\visual studio\vc\include\math.h(589): could be 'long double sqrt(long double)'
1>          d:\program files\visual studio\vc\include\math.h(541): or       'float sqrt(float)'
1>          d:\program files\visual studio\vc\include\math.h(127): or       'double sqrt(double)'
1>          while trying to match the argument list '(int)'


When reading the previous threads about this subject, it was suggested that the IDE may be the problem, and variable types were also mentioned. I tried changing the variable types to double, but it then threw out errors saying that i and n should be integers. What gives? While a caveat is offered about compatibility with multiple IDEs, it seems as though something like this should work across the board, though I'm purely speculating based on my extremely limited knowledge of C++. Any help is appreciated!
It's not an IDE problem.

The problem is sqrt does not have a version that takes an integer, and you are giving it an integer.

What you need to do is specify whether you want the float, double, or long double version. You do this by passing either a float, double or long double:

1
2
3
4
5
6
7
// either make 'n' a double
double n;

// or cast it to a double when you call sqrt:
double sq = sqrt( static_cast<double>(n) );
while (i <= sq) {
 //... 


It's also a bad (wasteful) idea to call sqrt in a loop if you can avoid it, as it is computationally expensive. Best to just call it once, throw the value in a variable and use the variable in the loop, as I did in the above example.
Thank you, Disch. I just switched "int n" to "double n", and I received the following error:

 
 error C2296: '%' : illegal, left operand has type 'double'


Were you saying that I needed to do something in addition to simply changing n's variable type? I'm sorry if I misread you.

Ok, I just adjusted the code to read what you've given me, and it works as it should:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#include <iostream>
#include <cmath>
using namespace std;

int main() {
	int i;
	int n;
	int is_prime = true;
	cout << "Enter a number: ";
	cin >> n;

	i = 2;
	double sq = sqrt(static_cast<double>(n));
	while (i <= sq) {
		if (n % i == 0)
			is_prime = false;
		i++;
	}

	if (is_prime)
		cout << "Number is prime" << endl;
	else 
		cout << "Number is not prime" << endl;

	return 0;
}


Thanks again for your input, Disch. I just took a look at the answer code that's provided for the book, and the author has exactly what you gave. I'm a little surprised that he would expect someone new to C++ to suddenly know about casting variables for an exercise when absolutely nothing on the subject was given to us up to that point. While it's obviously great to learn new things, I question that strategy. Then again, I'm now privy to the concept, so it appears that I'm whining about nothing.
Nah that's my mistake. I didn't see that you were modding n.

go with the other option instead. Keep n an int, but cast it to a double when you call sqrt.
Actually, I'd like to inquire about one more aspect of this code. The author improves on the following bit of code:

1
2
3
4
5
6
7
8
i=2
double sq = sqrt(static_cast<double>
while (i <= sq)
{
     if (n % i == 0)
          is_prime = false;
          i++;
}


......by adding break:
1
2
3
4
5
6
7
8
9
10
11
i=2
double sq = sqrt(static_cast<double>
while (i <= sq)
{
     if (n % i == 0)
     {
          is_prime = false;
          break;
     }
     i++;
     }


I understand that "break" tells it to get out of the loop, but why is the "i++" moved outside of the brackets? What exactly is happening?



Last edited on
In the first example, if (n % i == 0) is_prime = false; is all one statement, but in the second 'if' invokes multiple statements with the curly bracers, provided the condition in the brackets is true of course. Therefore, by looking at the if statement, i++ hasn't actually moved, it comes after the if statement each time. The only difference is that in the second example when n%i == 0, break occurs as well as setting the is_prime boolean to false.
That definitely helps. Thank you, Veltas!
Topic archived. No new replies allowed.