In C (linux) how will I be able to find out if the squareroot of a number is and integer or a floating point. I want to write a program using a function pointer which adds up all the Perfect squares upto the limit sepcified.
views:
145answers:
6float root = sqrt(number);
int int_root = (int) root;
if ( (root / (float)int_root) == 1.0f ) return "is integer";
That might work. Optimise it a bit.
or
float root;
if ((root % (int)root) == 0) { return "is integer";)
A simpler solution
int SUM_PERFECT_SQUARES (int limit) {
int sum = 0;
for (int i = 0; i < floor(sqrt(limit)); i++) {
sum += i*i;
}
return sum;
}
You may want to look up the paper what every computer scientist should know about floating point arithmetic by David Goldberg and rethink your question.
Here you go. Compile it with -lm
on Linux.
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
int checkRoot(double n) {
long n_sqrt = (long)(sqrt(n)+0.5);
return n_sqrt*n_sqrt == n;
}
int main() {
double n = 9.0;
if(checkRoot(n)) {
puts("Perfect root.");
}
else {
puts("Not quite.");
}
return EXIT_SUCCESS;
}
You can use the Newton-Ralphson method to implement square root for integers yourself. But, for the problem you're talking about, I would recommend calculating the squares of all the integers instead.
/* Returns the greatest integer that's <= to the square root. */
unsigned int isqrt(unsigned int x)
{
if (x < 4) {
return 1;
} else {
unsigned int try = x / 2;
while ((x / try) < try) {
try = (try + (x / try)) / 2;
}
return try;
}
}
int check_perfect_square(unsigned int x)
{
unsigned int sqrt = isqrt(x);
return (sqrt * sqrt) == x;
}
And, for my actual suggested solution:
unsigned int sum_perfect_squares(unsigned int limit)
{
unsigned int sum = 0;
unsigned int i = 1;
for (i = 1; i * i < limit; ++i) {
sum += i * i;
}
return sum;
}
Not really the answer you are looking for, but I think it is much better to simply sum up the squares of integers which fall into the range than try to use sqrt
to determine whether a number is a perfect square (As suggested in some of the comments to the question). This avoids having to use floating point values, which makes it a lot more reliable as a general purpose solution.
#include <stdio.h>
long long sum_squares(int limit){
int i;
long long ret=0;
for (i=1;i*i<=limit;i++){
ret+=i*i;
}
return ret;
}
int main(){
printf("%lld\n",sum_squares(10));
return 0;
}
Mathematical nit: Assuming your n
is an integer, the square root is never a floating point number. It's either an integer (in the case of perfect squares) or an irrational number (which cannot be represented at all except with special symbolic-math libraries).