224

I have a program in C++ (compiled using g++). I'm trying to apply two doubles as operands to the modulus function, but I get the following error:

error: invalid operands of types 'double' and 'double' to binary 'operator%'

Here's the code:

int main() {
    double x = 6.3;
    double y = 2;
    double z = x % y;
}
hichris123
  • 9,955
  • 15
  • 53
  • 68
Bhaxy
  • 5,136
  • 10
  • 36
  • 40
  • 15
    As has been noted, fmod() provides the necessary function. As has not yet been noted, it's important to realize that rounding errors in the second operand of `fmod` may cause unexpected behaviors. For example, `fmod(1, 0.1);` should mathematically be zero, but will in fact be almost 0.1. The extent of error goes up with the magnitude of the quotient. For example, `fmod(9E14, 0.1);` evaluates to about 0.05, which is from a mathematical standpoint just plain wrong. – supercat Jun 27 '13 at 21:32
  • 1
    @supercat more details would be awesome. I think have an idea of what's on behind the scenes to cause what you say to be true, but it would be good to see the reasons for why what you say is true; would be interesting to see how it works behind the scenes (I think I understand but could very easily be wrong). – RastaJedi Mar 18 '16 at 04:30
  • 4
    Floating-point values represent exact integer multiples or fractions of powers of two. For example, the integer literal 0.1 is exactly 3602879701896397/36028797018963968 (the latter value is a power of two). `fmod(x,0.1)` will divide x by that precise fraction and take the remainder, rather than dividing by the numerical value "one tenth". – supercat Mar 18 '16 at 14:26
  • 1
    Possible duplicate: [Why does modulus division (%) only work with integers?](https://stackoverflow.com/q/6102948/253056) – Paul R Jan 02 '18 at 22:55

4 Answers4

318

The % operator is for integers. You're looking for the fmod() function.

#include <cmath>

int main()
{
    double x = 6.3;
    double y = 2.0;
    double z = std::fmod(x,y);

}
Ayxan Haqverdili
  • 23,309
  • 5
  • 37
  • 74
Mysticial
  • 452,826
  • 45
  • 327
  • 325
  • 1
    I am programming in C++ for Qt and fmod has a bug there. The result of fmod(angle, 360) can be 360 (WAT?!) – Paul May 30 '17 at 07:39
  • 9
    @Paul: That's probably not a bug. If `angle` is, say, `359.9999999`, then both `angle` and `fmod(angle, 360)` are likely to be displayed as `360`. (Add more 9s as needed.) Try printing the values with, say, 50 digits of precision. – Keith Thompson Jan 02 '18 at 22:42
  • @Paul Qt's QString::format will round. If it is that critical, you will either have to round yourself or check the output for "360" and replace it with your own value. – jfh Mar 26 '20 at 21:30
  • 1
    @Rohan `main(void)` is not necessary in `C++` (it's C legacy) and your edit isn't improving anything else either. I reverted it back. – Ayxan Haqverdili Jan 22 '21 at 16:51
39

fmod(x, y) is the function you use.

MSN
  • 51,558
  • 7
  • 73
  • 102
5

You can implement your own modulus function to do that for you:

double dmod(double x, double y) {
    return x - (int)(x/y) * y;
}

Then you can simply use dmod(6.3, 2) to get the remainder, 0.3.

Mystical
  • 2,066
  • 2
  • 20
  • 35
4

Use fmod() from <cmath>. If you do not want to include the C header file:

template<typename T, typename U>
constexpr double dmod (T x, U mod)
{
    return !mod ? x : x - mod * static_cast<long long>(x / mod);
}

//Usage:
double z = dmod<double, unsigned int>(14.3, 4);
double z = dmod<long, float>(14, 4.6);
//This also works:
double z = dmod(14.7, 0.3);
double z = dmod(14.7, 0);
double z = dmod(0, 0.3f);
double z = dmod(myFirstVariable, someOtherVariable);
Sceptical Jule
  • 867
  • 1
  • 8
  • 20