# std::fmod(4.2, 0.12) is equal to epsilon * 1.5

``````auto a{ 4.2 };
auto b{ 0.12 };
auto result = std::fmod(a, b);
if(result <= std::numeric_limits<double>::epsilon())
result = 0; // <-- This line isn't triggered
``````

In this example, 4.2 is actually equal to `4.2000000000000002` due to `double` imprecision.

Note that 4.2/0.12 = 35.

I would expect the output to be equal to `std::numeric_limits<double>::epsilon()`. Instead, result is equal to `1.5 * std::numeric_limits<double>::epsilon()`.

Where does this 1.5 multiplier come from?

• Why would you expect the result to be equal to exactly `epsilon`? To verify why it is `1.5*epsilon`, you can bring `4.2` and `0.12` into their binary form and then calculate the remainder.
– chtz
Aug 20, 2020 at 7:31
• The size of the steps between the `double` numbers in [1, 2) is `epsilon`. The size of the steps between the `double` numbers in [4, 8), in which 4.2 lies, is `4*epsilon`. The size of the steps between the `double` numbers in [.0625, .125), in which .12 lies, is `epsilon/16`. Let’s call these steps, `epsilon/16`, `s`. The `double` nearest 4.2 is apparently `24*s` away from the nearest multiple of the `double` nearest .12. `24*s` is `1.5*epsilon`. That is where the 1.5 comes from. Aug 20, 2020 at 9:27

The result of `std::fmod` may be expected to be accurate to within a ULP or so, but the machine epsilon is the ULP of 1, not of the result of any given operation.
• `fmod` is one of the few floating point operations that always should be exact (assuming all inputs are finite and the divisor is not zero).