11

Is there any predefined function in c++ to check whether the number is square of any number and same for the cube..

Douglas B. Staple
  • 10,510
  • 8
  • 31
  • 58
d3vdpro
  • 2,887
  • 4
  • 25
  • 29

9 Answers9

21

No, but it's easy to write one:

bool is_perfect_square(int n) {
    if (n < 0)
        return false;
    int root(round(sqrt(n)));
    return n == root * root;
}

bool is_perfect_cube(int n) {
    int root(round(cbrt(n)));
    return n == root * root * root;
}
C. K. Young
  • 219,335
  • 46
  • 382
  • 435
  • Where do you see a possible division by zero ? sqrt(0) and cbrt(0) are defined. – Pierre Bourdon Oct 11 '09 at 05:48
  • The original answer I had in my mind used return `n / root == root`, but I ended up using a different approach. Thanks for pointing out! Will edit answer. – C. K. Young Oct 11 '09 at 05:52
  • 4
    This won't always work, due to floating-point error: if `sqrt()` or `cbrt()` happens to return epsilon less than the actual root, the cast to an integer will truncate that, and the check will fail. To be completely bullet-proof against that, you also need to check if `n == (root + 1) * (root + 1)` for the square root case or if `n == (root + 1) * (root + 1) * (root + 1)` for the cube root case. – Adam Rosenfield Oct 11 '09 at 17:52
  • 47
    Oh god, it hurts my head. I kept looking for the "root" function until I realized you were just initializing an integer... I strongly dislike your coding style. – mpen Oct 11 '09 at 17:53
  • @Adam: Do you have a case where an "integral" result from `sqrt` or `cbrt` would end up to be "epsilon less than the root"? Remember we're not dealing with fractions here, so (assuming that the root isn't so big that it can't be represented exactly by a floating point number, in which case we've lost already), how will this be a problem? I'm happy to use `round()` though. – C. K. Young Oct 11 '09 at 18:53
  • 4
    @Mark: You can dislike it all you want, but it's the "more-standard" initialisation style in C++; I think it's called "constructor syntax" or something like that. i.e., if you are constructing an object that, say, takes more than one constructor parameter, you'd have to use that syntax anyway. I don't like to make a special exception for numeric types, so I use constructor syntax for them too. – C. K. Young Oct 11 '09 at 18:57
  • 6
    Oh god, I just came back to this question and tried to leave the same comment, then noticed someone else already did, then tried to upvote them but couldn't find the up arrow, then looked at the user, and realized it was me. Wouldn't it be faster to check `abs(root-round(root)) <= epsilon`, rather than multiplying? – mpen Jul 20 '11 at 01:26
  • 2
    This is called direct initialization. But brace initialization is preferred over using parentheses as it eliminates the problem of most vexing parse. – stillanoob Jul 31 '17 at 13:44
6

sqrt(x), or in general, pow(x, 1./2) or pow(x, 1./3)

For example:

int n = 9;
int a = (int) sqrt((double) n);
if(a * a == n || (a+1) * (a+1) == n)  // in case of an off-by-one float error
    cout << "It's a square!\n";

Edit: or in general:

bool is_nth_power(int a, int n) {
  if(n <= 0)
    return false;
  if(a < 0 && n % 2 == 0)
    return false;
  a = abs(a);

  int b = pow(a, 1. / n);
  return pow((double) b, n) == a || pow((double) (b+1), n) == a;
}
Jesse Beder
  • 33,081
  • 21
  • 109
  • 146
  • 2
    The problem with using `pow(x, 1./3)` is that 1/3 does not have an exact representation in floating point, so you're not "really" getting the cube root. C99 onwards has `cbrt`, which should do a better job of getting the cube root. – C. K. Young Oct 11 '09 at 05:45
  • I suppose. But `pow` generalizes easier, and it's easy enough to correct for floating point errors. – Jesse Beder Oct 11 '09 at 05:48
2

No, there are no standard c or c++ functions to check whether an integer is a perfect square or a perfect cube.

If you want it to be fast and avoid using the float/double routines mentioned in most of the answers, then code a binary search using only integers. If you can find an n with n^2 < m < (n+1)^2, then m is not a perfect square. If m is a perfect square, then you'll find an n with n^2=m. The problem is discussed here

Douglas B. Staple
  • 10,510
  • 8
  • 31
  • 58
1

Try this:

#include<math.h>
int isperfect(long n)
{
    double xp=sqrt((double)n);
    if(n==(xp*xp))
        return 1;
    else
        return 0;
}
Ben
  • 51,770
  • 36
  • 127
  • 149
nikoo28
  • 2,961
  • 1
  • 29
  • 39
1

The most efficient answer could be this

    int x=sqrt(num)
    if(sqrt(num)>x){
    Then its not a square root}
    else{it is a perfect square}

This method works because of the fact that x is an int and it will drop down the decimal part to store only the integer part. If a number is perfect square of an integer, its square root will be an integer and hence x and sqrt(x) will be equal.

Saurabh Kumar
  • 2,088
  • 14
  • 17
0

For identifying squares i tried this algorithm in java. With little syntax difference you can do it in c++ too. The logic is, the difference between every two consecutive perfect squares goes on increasing by 2. Diff(1,4)=3 , Diff(4,9)=5 , Diff(9,16)= 7 , Diff(16,25)= 9..... goes on. We can use this phenomenon to identify the perfect squares. Java code is,

    boolean isSquare(int num){
         int  initdiff = 3;
         int squarenum = 1;
         boolean flag = false;
         boolean square = false;
         while(flag != true){

                if(squarenum == num){

                    flag = true;
                    square = true;

                }else{

                    square = false;
                 }
                if(squarenum > num){

                    flag = true;
                }
            squarenum = squarenum + initdiff;
            initdiff = initdiff + 2;
   }
              return square;
 }  

To make the identification of squares faster we can use another phenomenon, the recursive sum of digits of perfect squares is always 1,4,7 or 9. So a much faster code can be...

  int recursiveSum(int num){
     int sum = 0;   
     while(num != 0){
     sum = sum + num%10;
     num = num/10;         
     }
     if(sum/10 != 0){         
        return recursiveSum(sum);     
     }
     else{
         return sum;
     }

 }
  boolean isSquare(int num){
         int  initdiff = 3;
         int squarenum = 1;
         boolean flag = false;
         boolean square = false;
         while(flag != true){

                if(squarenum == num){

                    flag = true;
                    square = true;

                }else{

                    square = false;
                 }
                if(squarenum > num){

                    flag = true;
                }
            squarenum = squarenum + initdiff;
            initdiff = initdiff + 2;
   }
              return square;
 }  

   boolean isCompleteSquare(int a){
    // System.out.println(recursiveSum(a));
     if(recursiveSum(a)==1 || recursiveSum(a)==4 || recursiveSum(a)==7 || recursiveSum(a)==9){

         if(isSquare(a)){

             return true;

         }else{
             return false;
         }


     }else{

         return false;


     }

  }
Deepeshkumar
  • 395
  • 3
  • 13
-1

For perfect square you can also do:

if(sqrt(n)==floor(sqrt(n)))
    return true;
else
    return false;

For perfect cube you can:

if(cbrt(n)==floor(cbrt(n)))
    return true;
else
    return false;

Hope this helps.

Prashant Shubham
  • 456
  • 8
  • 20
  • _IF_ this was "about return", why not just `return sqrt(n)==floor(sqrt(n))`? (and why prefer `floor` to `round`?) Then, there is `int r = round(cbrt(n)); return n == r*r*r` - none of which is `predefined`, leaving _not to our 2016 knowledge_: [Chris' answer](http://stackoverflow.com/a/1549960/3789665). – greybeard Aug 23 '16 at 06:01
  • Due to floating point roundoffs, this is not a good way to do the cube check. This will fail on `n == 27`: [Try it online!](https://tio.run/##TY3LCsIwEEX38xWhImRAQdy4qO2mX5LmoYF0UvJYid8exxd0VvceOHf0uh51UHRrbedJh2qsuOpcjI8jbMiiyn0ET0X4PM3yHQgfILyTek5FEg6DCzGmf0UEwZdsqYlESdX2IGzIdoudYtDD8zO8KE8SgUfXxN3Jbm@6w/ff@YLI/k87sdLaCw "C++ (clang) – Try It Online") – General Grievance Feb 11 '21 at 21:38
-1

We could use the builtin truc function -

#include <math.h>

// For perfect square
bool is_perfect_sq(double n) {
    double r = sqrt(n);
    return !(r - trunc(r));
}

// For perfect cube
bool is_perfect_cube(double n) {
    double r = cbrt(n);
    return !(r - trunc(r));
}
Gautham
  • 766
  • 7
  • 15
-2
bool isSquare(int n) {
    return floor(sqrt(n)) == ceil(sqrt(n));
}

bool isQube(int n) {
    return floor(cbrt(n)) == ceil(cbrt(n));
}
  • Your cube root checker fails at certain values, such as 27. – General Grievance Feb 11 '21 at 13:13
  • Please don't post only code as answer, but also provide an explanation what your code does and how it solves the problem of the question. Answers with an explanation are usually more helpful and of better quality, and are more likely to attract upvotes. – Mark Rotteveel Feb 11 '21 at 17:14