'Implementation of FMOD function

How is the fmod function implemented?

I tried the following:

#include <stdio.h>
#include <math.h>

float floatMod(float a, float b)
{
  return (a/b - floor(a/b));
}

int main()
{
  printf("%f\n", fmod(18.5,4.2));
  printf("%f\n", floatMod(18.5,4.2));
}

But the output is not the same...

c


Solution 1:[1]

Your fmod function should be:

float floatMod(float a, float b)
{
    return (a - b * floor(a / b));
}

LIVE DEMO


UPDATE 7-Feb-2020

As pointed out by @s3cur3 et al in the comments below, the implementation above does not give correct results (as in matching the standard library fmod() function) when the first argument is negative. Using the definition in this answer a more correct implementation would be:

float floatMod(float a, float b)
{
    return a - (round(a / b) * b);
}

LIVE DEMO

Apparently the update is broken too (see comment from @Bernard below) - I would delete the answer but it's been accepted, so I'll try and get back to it and fix it in the near future.

Solution 2:[2]

A correct implementation of fmod function in C/C++ is:

#include <iostream>
using namespace std;
#include <math.h> //for trunc()

double MyFmod(double x, double y) {
  return x - trunc(x / y) * y;
}

//test it
int main() 
{
  double values[13] = {-10.9, -10.5, -10.4, -0.9, -0.5, -0.1, 0, 0.1, 0.5, 0.9, 10.4, 10.5, 10.9};
  for (size_t i = 0; i < 12; ++i)
    cout << fmod(values[i], 3.0) <<" "<< MyFmod(values[i], 3.0) << endl;

  for (size_t i = 0; i < 12; ++i)
    cout << fmod(values[i], -3.0) <<" "<< MyFmod(values[i], -3.0) << endl;
  
  return 0;
}

A correct implementation of fmod function in Java is:

//trunc() implementation in Java:
double truncate(double x) {
  return x < 0 ? -Math.floor(-x) : Math.floor(x);
  //or return x < 0 ? Math.ceil(x) : Math.floor(x);
}

double MyFmod(double x, double y) {
  return x - truncate(x / y) * y;
}

One also could use fma instruction to improve precision (although this will work correctly only when result of trunc(x/y) is computed exactly):

C/C++: fma(trunc(x / y), -y, x);

Java: Math.fma(truncate(x / y), -y, x);

Note: When the accuracy of double is not enough, all the above implementations are probably inferior to the compiler's math library. In my compiler, std::fmod(1e19, 3) computes 1.0 (accurate result), while MyFmod with same arguments, returns -512.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2