4

why doesn´t ((num / i) % 1 == 0) work in C++ when num is a double? and how would I instead write this code, that checks for factorials by checking if it leaves a remainder (etc 0.3333).

int getFactorials (double num)
{
    int total = 0;      // if (total / 2) is equal too 'num' it is a perfect number.

    for (int i = 1; i < num; i++)
    {
        if ((num / i) % 1 == 0)
        {
            cout << i << endl;
        }
    }
    return 0;
}
Potatoswatter
  • 134,909
  • 25
  • 265
  • 421
Tom Lilletveit
  • 1,872
  • 3
  • 31
  • 57

4 Answers4

7

The % operator is only allowed on integral types (and user defined types which overload it). For floating point, you need the function fmod.

James Kanze
  • 150,581
  • 18
  • 184
  • 329
6

Actually what you want to do is check if n is divisible by i so all you have to change is

if ((num / i) % 1 == 0)

into

if (num % i == 0) 

You should know that this is error-prone because you are using double as a type for num. You should use an int instead.

alestanis
  • 21,519
  • 4
  • 48
  • 67
  • Shouldn't `(num / i) % 1 == 0` work too? (if rounding errors didn't exist) – irrelephant Nov 09 '12 at 09:33
  • if (num % i == 0) would not work. for example if I divide 28 by 4 the answer is 7 not zero, but 4 is an divisor of 28 – Tom Lilletveit Nov 09 '12 at 09:38
  • 2
    @TomLilletveit The `%` operator gives you the **remainder** of the division of `n` by `i`, so if `i` divides `n` it will give you zero. – alestanis Nov 09 '12 at 09:50
  • Note that casting to `int` doesn't work unless the `double` is really supposed to be close to an integer value. And since floating point numbers don't represent integers exactly once the exponent part is large, they shouldn't be used as such. Use `long long` for large integers. – Potatoswatter Nov 09 '12 at 10:05
2

The % operator is defined by C++11 §5.6/4:

if the quotient a/b is representable in the type of the result, (a/b)*b + a%b is equal to a.

This is meaningless for floating point types. The definition of modulus depends on division rounding to an integer.

As James Kanze says, use std::fmod instead.

Potatoswatter
  • 134,909
  • 25
  • 265
  • 421
0

This code return you a double object

(num / i)

modulo operation is allowed only for int type. You can convert this to int type

( ((int) (num / i) ) % i)
Jacek
  • 11,661
  • 23
  • 69
  • 123