Optimized way to find if a number is a perfect square
I was wondering if the number was a perfect square or not:
A perfect square is an element of an algebraic structure that is equal to the square of another element.
For example: 4, 9, 16, etc.
My friends, if n
is a number, they were looping around n - 1
, calculating n * n
:
// just a general gist
int is_square = 0;
for (int i = 2; i < n; i++)
{
if ((i * i) == n)
{
std::cout << "Yes , it is";
is_square = 1;
break;
}
}
if (is_square == 0)
{
std::cout << "No, it is not";
}
I came up with a solution as shown below:
if (ceil(sqrt(n)) == floor(sqrt(n)))
{
std::cout << "Yes , it is";
}
else
{
std::cout << "no , it is not";
}
And it works right.
Is it a more streamlined solution than others?
source to share
You will need to know the complexity of the sqrt (x) function on your computer in order to compare it with other methods. By the way, you are calling sqrt (n) twice; consider storing it in a variable (even if the compiler will probably do it for you).
If you are using something like Newton's method, the complexity of sqrt (x) is in O(M(d))
, where M (d) measures the time it takes to multiply two d-digit numbers. Wikipedia
Your friend method is doing (n - 2) multiplications (worst case scenario), so its complexity is similar to O(n * M(x))
where x is a growing number.
Your version only uses sqrt () (ceil and floor can be ignored due to their constant complexity) making it O(M(n))
.
O(M(n)) < O(n * M(x))
- Your version is more optimized than your friend's, but not the most efficient one. Take a look at the interjay link for a better approach.
source to share
I don't know what limits you have, but a great definition of a square number is clear
Another way to say that a (non-negative) number is a square number is that its square roots are again integers on wikipedia
IF SQRT(n) == FLOOR(SQRT(n)) THEN
WRITE "Yes it is"
ELSE
WRITE "No it isn't"
Examples sqrt (9) == floor (sqrt (9)) , sqrt (10) == floor (sqrt (10))
source to share
I recommend this
if(((unsigned long long)sqrt(Number))%1==0) // sqrt() from math library
{
//Code goes Here
}
This works because ... all integers (and only positive integers) are positive multiples of 1
and hence the solution .....
You can also run a test test; I did with the following code in MSVC 2012
#include <iostream>
#include <conio.h>
#include <time.h>
#include <math.h>
using namespace std;
void IsPerfect(unsigned long long Number);
void main()
{
clock_t Initial,Final;
unsigned long long Counter=0;
unsigned long long Start=Counter;
Start--;
cout<<Start<<endl;
Initial=clock();
for( Counter=0 ; Counter<=100000000 ; Counter++ )
{
IsPerfect( Counter );
}
Final=clock();
float Time((float)Final-(float)Initial);
cout<<"Calculations Done in "<< Time ;
getch();
}
void IsPerfect( unsigned long long Number)
{
if(ceil(sqrt(Number)) == floor(sqrt(Number)))
//if(((unsigned long long)sqrt(Number))%1==0) // sqrt() from math library
{
}
}
Your code took 13590 time units
Mine only 10,049 units of time
Also, I use a few extra steps that involve type conversion
as
(unsigned long long)sqrt(Number))
Without it, he can do even better.
Hope this helps .....
To have a good day....
source to share