Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
407 views
in Technique[技术] by (71.8m points)

c++ - Why am I getting a different result from std::fmod and std::remainder

In the below example app I calculate the floating point remainder from dividing 953 by 0.1, using std::fmod

What I was expecting is that since 953.0 / 0.1 == 9530, that std::fmod(953, 0.1) == 0

I'm getting 0.1 - why is this the case?

Note that with std::remainder I get the correct result.

That is:

std::fmod     (953, 0.1) == 0.1 // unexpected
std::remainder(953, 0.1) == 0   // expected

Difference between the two functions:

According to cppreference.com

  • std::fmod calculates the following:

exactly the value x - n*y, where n is x/y with its fractional part truncated

  • std::remainder calculates the following:

exactly the value x - n*y, where n is the integral value nearest the exact value x/y

Given my inputs I would expect both functions to have the same output. Why is this not the case?

Exemplar app:

#include <iostream>
#include <cmath>

bool is_zero(double in)
{
    return std::fabs(in) < 0.0000001;
}

int main()
{
    double numerator   = 953;
    double denominator = 0.1;

    double quotient = numerator / denominator;
    double fmod     = std::fmod     (numerator, denominator);
    double rem      = std::remainder(numerator, denominator);

    if (is_zero(fmod))
        fmod = 0;
    if (is_zero(rem))
        rem = 0;

    std::cout << "quotient: " << quotient << ", fmod: " << fmod << ", rem: " << rem << std::endl;
    return 0;
}

Output:

quotient: 9530, fmod: 0.1, rem: 0
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Because they are different functions.

std::remainder(x, y) calculates IEEE remainder which is x - (round(x/y)*y) where round is rounding half to even (so in particular round(1.0/2.0) == 0)

std::fmod(x, y) calculates x - trunc(x/y)*y. When you divide 953 by 0.1 you may get a number slightly smaller than 9530, so truncation gives 9529. So as the result you get 953.0 - 952.9 = 0.1


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...