3
#include <stdio.h>
#include <cs50.h>
#include <unistd.h>
#include <math.h>

void rationalSquareRoots(void);

int main(void) {
    rationalSquareRoots();
}

void rationalSquareRoots(void) {
    for(float i = 0; ; i++) {
    if(sqrt(i) % 1 == 0) {
        printf("%f\n", i);
    }
    sleep(1);
    }
}

I've encountered the following problem while attempting to make a program which prints out all numbers with rational square roots (well, all numbers up to the point of overflowing, I guess).

14:19: error: invalid operands to binary expression ('double' and 'int')
    while(sqrt(i) % 1 == 0) {

The problem seems to be in the % operator? Is it not supported in if statements? What's the solution?

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
UrosDjosic
  • 45
  • 4
  • 1
    The `%` operatoris not supported for floating point values, which is what `sqrt` returns. – Retired Ninja Jul 08 '22 at 16:53
  • If you want modulo for floats, use fmod function. Also I recommend reading [this](https://stackoverflow.com/questions/5796983/checking-if-float-is-an-integer) thread. – Nierusek Jul 08 '22 at 16:54
  • 1
    You could start with rational numbers and print their squares... – Weather Vane Jul 08 '22 at 16:56
  • 1
    Aside: never use the inferior `float` without a compelling reason why you can't use `double`. Note that `double sqrt(double x);` isn't using the `float` type. – Weather Vane Jul 08 '22 at 17:07
  • Side note: your question says "all numbers with rational square roots", but your program is evidently trying to print numbers with *integral* square roots. 2.25 (aka 9/4) is an example of a number with a [rational](https://en.wikipedia.org/wiki/Rational_number) square root which isn't integral. – Steve Summit Jul 08 '22 at 17:37
  • @SteveSummit And indeed, the _only_ numbers with rational square roots are those whose numerator and denominator are squares of integers (discarding 0 as a candidate for the denominator). – Ian Abbott Jul 08 '22 at 17:50
  • There are countably infinite numbers with rational square roots. Are you planning to print them all? – Ian Abbott Jul 08 '22 at 17:51
  • Numerical checking if number is rational is very complicated – 0___________ Jul 08 '22 at 18:00
  • In my first comment above, I should have clarified that the only numbers with rational square roots are those whose numerator and denominator **in their simplest form** are squares of integers. For example 8/18 has a rational square root but is not in its simplest form. (The simplest form is 4/9 and the rational square root is 2/3.) – Ian Abbott Jul 08 '22 at 18:06

2 Answers2

2

The % operator is only for divisions between integers.

To calculate remainders of floating-point divisions, you should use fmod() function.

Using this function, the condition should be fmod(sqrt(i), 1) == 0.

MikeCAT
  • 73,922
  • 11
  • 45
  • 70
0

The error is caused by the fact the modulo (%) is defined only for integers in C and C++. sqrt(i) returns a double (which it should, as square roots of integers can have infinite decimal digits), hence causing an error.

You can totally do what you're doing here, with use of the fmod function instead.

However, I will also offer an alternative implementation which, in terms of time complexity, is much more efficient. Instead of iterating through the integers and checking if their square roots are rational, simply output the square numbers.

I understand that you may be doing this as a practice for the C operators (or practice for C in general), but maybe someone will find this useful.

void rationalSquareRoots(void) {
    for(float i = 0; ; i++) {
        printf("%f\n", i*i);
//        sleep(1);
          sleep((i+1)*(i+1)-i*i); //to give the same behaviour as your provided code
    }
}
Ryan Zhang
  • 1,856
  • 9
  • 19
  • `sleep((i+1)*(i+1)-i*i);` instead of `sleep(1);` may be better for compatibility. – MikeCAT Jul 08 '22 at 16:56
  • @MikeCAT Thank you. I've added this to my answer. – Ryan Zhang Jul 08 '22 at 17:01
  • 1
    thanks mate! I'm following the cs50 starter course online and the teacher man said that the best way to code is to develop your logic or something, so it wasn't the syntax itself which was important for beginners, but the way we approach problems. This was just my idea of doing so, but I appreciate your suggestion either way. – UrosDjosic Jul 08 '22 at 17:14
  • will it display result of `(3/7)*(3/7)`? – 0___________ Jul 08 '22 at 18:02
  • @0___________ No it won't. Nor will OP's code. If you've read OP's code sample, OP is referring to all integers with rational square roots. – Ryan Zhang Jul 09 '22 at 01:15
  • @RyanZhang so this code makes no sense for floats – 0___________ Jul 09 '22 at 14:48
  • @0___________ what do you mean? Are you saying I should be using `int` instead? I used floats to match OP's `printf` statement. – Ryan Zhang Jul 09 '22 at 14:59
  • OPs code is basically invalid and cannot be repaired - it has to be rewritten. The task is very complex – 0___________ Jul 09 '22 at 15:00