How to check whether result is an integer or no?

Like, i wanna check whether sqrt(c) is an integer?
Interesting question. I guess someone with good knowledge on the IEEE floating point specification can give a super fast and awesome answer here. In the meantime, I can only think of a lame suggestion: Use a string stream to convert the number to string and determine if the decimal symbol is present.

But in all honesty, that is soooo lame that I wouldn't dare use it in production code. There has to be a better way.
Is c an integer? If so then maybe this:
1
2
3
4
5
6
7
8
9
10
11
12
13
#include <cmath>
#include <iostream>

int main()
{
	for(int i = 0; i < 100; ++i)
	{
		double root = std::sqrt(double(i));

		if(int(root + 0.5) * int(root + 0.5) == i) // is root integer?
			std::cout << i << '\n';
	}
}
0
1
4
9
16
25
36
49
64
81

Last edited on
Nice, Galik. Much more decent and clever for sure. Yes, c must be an integer for the root to have any chance of being an integer too. After all, there are no integers that squared yield a real number, and therefore if root is integer, so it is its square.
Last edited on
Assuming you are entering only int arguments the above make sense.

Otherwise I guess round off errors forbids the use of the above equality condition.

I would have suggested something like (int)root == root but does not works well when round off errors give results as 2.9999 instead of 3.

Good one @Galik.
sqrt() is guaranteed to yield, I think, 1ulp precision (who has LIA-2 at hand, check), so you can simply compare to the nearest integer with appropriately-scaled epsilon. Borrowing Galik's loop:

1
2
3
4
5
6
7
8
9
10
11
12
#include <cmath>
#include <limits>
#include <iostream>
int main()
{
    for(int i = 0; i < 100; ++i)
    {
        double root = std::sqrt(i);
        if( std::abs(root - std::floor(root))  < root*std::numeric_limits<double>::epsilon() )
            std::cout << i << '\n';
    }
}

demo: http://ideone.com/Ufhmd


Topic archived. No new replies allowed.