Fmod(double, double) - problem


#1

Hello,
could anyone tells me why:
std::cout << fmod(0.90, 0.10) << std::endl;

gives me result: 0.1
While std::cout << fmod(0.80, 0.10) << std::endl; works OK and gives me 0
I can’t understand that behaviour.
For any help thanks in advance.
Best Regards


#2

Sounds like a problem regarding the numerical resolution of double, which should be very good but apparently it isn’t when it comes down to your specific use-case.

The precision of floating point values (that’s float or double) is high but not perfect. Dividing 0.9 by 0.1 will result in 8.9999… due to that precision.
When you look at https://en.cppreference.com/w/cpp/numeric/math/fmod you will see how the function works: the fractional part is truncated so that will return 8 and gives you a fractional part of 0.99999999… the result of fmod is x - n*y = 0.9 - 8* 0.1 = 0.1


#3

Thanks, I also thought it’s something about precision of float or double. But how to solve it? I need to make
if( fmod(someDoubleValue, 0.1) == 0 ) // do something
But in that case it doesn’t work for me.


#4

That depends on what exactly you want to achieve. You could check if the remainder is about the same as the divisor, that could be a hint that that case just occurred.
But again, depends on what behavior you want to have.


#5

Actually you will probably laughing at me :slight_smile: I need to achieve something probably very easy:
I want my Slider tex box show values always with the same precision, with the zeros after coma.
Now I have Slider.setRange(0.00, 8.00, 0.01). And for fractional numbers it works OK. For example 1.88, in the Slider text box looks 1.88. Great. But for integers it just cuts the dot and zeros. So I decided to do that:

mySlider.textFromValueFunction = [](double value)
{
        if(fmod(value, 1.0) == 0) //For integers - IT WORKS OK
            return juce::String(value) + ".00";
        if(fmod(value, 0.1) == 0) //One number after comma - IT DOESN'T WORK
            return juce::String(value) + "0";
        else
            return juce::String(value);
}

Just simple like that. I suppose there is some much easier method to achieve that. But I am not good in googling :slight_smile:


#6

String (value, 2); will do the job :wink:


#7

thanks :slight_smile: