#include <stdio.h> 
#include <math.h> 

int main(void) 

{ 
int number; 
double result; 

printf ("\n Introduce an integer: "); 

scanf ("%i", &number); 

result= sqrt (number); 

if ((result * result)== number) 
printf ("\n The integer HAS a perfect square \n\n"); 

else 
printf ("\n The integer DOES NOT HAVE a perfect square \n\n"); 

}

although, this code gives me correct output for values, but i wana ask is it the right way to check that a number is a perfect square ? as i am taking result as double which always a approximate value so multiplying this (result*result) will give me the correct output ? thanks in advance.

as i am taking result as double which always a approximate value so multiplying this (result*result) will give me the correct output ?

Your concern is justified. To be strictly correct your equality check should add a fudge factor:

result *= result;

if (fabs(result - number) < FUDGE)
    puts("The integer is a perfect square");
else
    puts("The integer is not a perfect square");

FUDGE would be defined as the precision to which you consider numbers to be equal. So something like const double FUDGE = 0.0001 for a few digits of precision.

firstly fabs is the function which return absolute value and number is the number which i wana check. right ? so you are checking that difference betweem them should be less than 0.0001 ? will it give the correct answer in every case ? confirmed ? can there be any case in which it can give error ?

I would sqrt cast to long integer and use exact equality check of it's square against the integer number.

Edited 4 Years Ago by pyTony

result= sqrt (number);

doesn't sqrt() take argument of type "double" by default??

the book says sqrt() will return non sensical values if given argument of type int? but it seems to work.. so why say that in the book?

Edited 4 Years Ago by somjit{}

100% correct! i also remeber that i have read it somehere, please deceptikon throw some light on this also which somjit{} is saying thanks.

doesn't sqrt() take argument of type "double" by default??

No, it takes an argument of type double absolutely.

the book says sqrt() will return non sensical values if given argument of type int?

Which book is "the book"? If you pass an int to sqrt(), it will be promoted to double. The two types are compatible because double can exactly represent any value in the range of int. In this case I'd say either your book is simply wrong, or you're misinterpreting what it says.

Which book

ANSI C @ dennis ritchie, pg 45 lower part

"the book"?

i think so ;) \m/

and well, i think im misinterpreting it ... coz i just ran the code, and it works too...

in case of integer, itsays to cast it into double, like

sqrt((double)int);

whats happening here ?

Edited 4 Years Ago by somjit{}

i know you have read it from dennis, i was going to guess it ;) i have also read it 2 times till date. ;) read it thoroughly, just watching your comment, i was also confused. thanks

When you do this:

sqrt(123);

It's functionally identical to this:

double temp = 123;
sqrt(temp);

The integer value is assigned to a double parameter, which is perfectly legal as I described above.

I don't have my hardcopy of K&R handy right now, so I can't fact check what it says, but the cast isn't required, and sqrt() is well behaved when given integer values. In C++ you'll get ambiguity errors due to overloading of sqrt(), but in C it's all good.

Edited 4 Years Ago by deceptikon

I meant casting the result to long int and squaring, then find if it equals. Or round as alternative to cast.

Considering what has already been posted here my full code:

#include <stdio.h>
#include <math.h>
#include <stdlib.h>

int main(void)
{
    int number;
    long result;

    printf("\n Introduce an integer: ");
    scanf("%i", &number);
    result = (long)sqrt(number);
    printf("\n The integer IS");
    printf(((result * result)== number)? "":" NOT");
    printf(" a perfect square \n\n");

    return EXIT_SUCCESS;
}

Edited 4 Years Ago by pyTony

printf(((result * result)== number)? "":" NOT");

thats a neat way to print ;) gonna do that myself when possible :)

thats a neat way to print ;) gonna do that myself when possible :)

Don't do it because it's neat. Do it when it makes the code easier to read.

This article has been dead for over six months. Start a new discussion instead.