How to correctly and standardly compare floats?












24














Every time I start a new project and when I need to compare some float or double variables I write the code like this one:



if (fabs(prev.min[i] - cur->min[i]) < 0.000001 &&
fabs(prev.max[i] - cur->max[i]) < 0.000001) {
continue;
}


Then I want to get rid of these magic variables 0.000001(and 0.00000000001 for double) and fabs, so I write an inline function and some defines:



#define FLOAT_TOL 0.000001


So I wonder if there is any standard way of doing this? May be some standard header file?
It would be also nice to have float and double limits(min and max values)










share|improve this question




















  • 2




    Might want to look at this stackoverflow.com/questions/17333/…
    – Dr G
    Dec 28 '10 at 17:40






  • 1




    Depends on the use case, but what about very small numbers? Your code would compare 1e-10 and 1e-15 and -1e-10 as all equal. There is no single "correct" way to compare floating point numbers for "closeness".
    – aschepler
    Dec 28 '10 at 18:02






  • 4




    Why #define? You can just use a static const float for this purpose.
    – Puppy
    Dec 28 '10 at 18:11










  • I bet you forgot to compare with 0? :)
    – user2771260
    Sep 12 '13 at 5:13
















24














Every time I start a new project and when I need to compare some float or double variables I write the code like this one:



if (fabs(prev.min[i] - cur->min[i]) < 0.000001 &&
fabs(prev.max[i] - cur->max[i]) < 0.000001) {
continue;
}


Then I want to get rid of these magic variables 0.000001(and 0.00000000001 for double) and fabs, so I write an inline function and some defines:



#define FLOAT_TOL 0.000001


So I wonder if there is any standard way of doing this? May be some standard header file?
It would be also nice to have float and double limits(min and max values)










share|improve this question




















  • 2




    Might want to look at this stackoverflow.com/questions/17333/…
    – Dr G
    Dec 28 '10 at 17:40






  • 1




    Depends on the use case, but what about very small numbers? Your code would compare 1e-10 and 1e-15 and -1e-10 as all equal. There is no single "correct" way to compare floating point numbers for "closeness".
    – aschepler
    Dec 28 '10 at 18:02






  • 4




    Why #define? You can just use a static const float for this purpose.
    – Puppy
    Dec 28 '10 at 18:11










  • I bet you forgot to compare with 0? :)
    – user2771260
    Sep 12 '13 at 5:13














24












24








24


10





Every time I start a new project and when I need to compare some float or double variables I write the code like this one:



if (fabs(prev.min[i] - cur->min[i]) < 0.000001 &&
fabs(prev.max[i] - cur->max[i]) < 0.000001) {
continue;
}


Then I want to get rid of these magic variables 0.000001(and 0.00000000001 for double) and fabs, so I write an inline function and some defines:



#define FLOAT_TOL 0.000001


So I wonder if there is any standard way of doing this? May be some standard header file?
It would be also nice to have float and double limits(min and max values)










share|improve this question















Every time I start a new project and when I need to compare some float or double variables I write the code like this one:



if (fabs(prev.min[i] - cur->min[i]) < 0.000001 &&
fabs(prev.max[i] - cur->max[i]) < 0.000001) {
continue;
}


Then I want to get rid of these magic variables 0.000001(and 0.00000000001 for double) and fabs, so I write an inline function and some defines:



#define FLOAT_TOL 0.000001


So I wonder if there is any standard way of doing this? May be some standard header file?
It would be also nice to have float and double limits(min and max values)







c++ floating-point floating-accuracy double-precision






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited May 11 '12 at 14:44









mskfisher

2,11832741




2,11832741










asked Dec 28 '10 at 17:38









Dmitriy

2,88253452




2,88253452








  • 2




    Might want to look at this stackoverflow.com/questions/17333/…
    – Dr G
    Dec 28 '10 at 17:40






  • 1




    Depends on the use case, but what about very small numbers? Your code would compare 1e-10 and 1e-15 and -1e-10 as all equal. There is no single "correct" way to compare floating point numbers for "closeness".
    – aschepler
    Dec 28 '10 at 18:02






  • 4




    Why #define? You can just use a static const float for this purpose.
    – Puppy
    Dec 28 '10 at 18:11










  • I bet you forgot to compare with 0? :)
    – user2771260
    Sep 12 '13 at 5:13














  • 2




    Might want to look at this stackoverflow.com/questions/17333/…
    – Dr G
    Dec 28 '10 at 17:40






  • 1




    Depends on the use case, but what about very small numbers? Your code would compare 1e-10 and 1e-15 and -1e-10 as all equal. There is no single "correct" way to compare floating point numbers for "closeness".
    – aschepler
    Dec 28 '10 at 18:02






  • 4




    Why #define? You can just use a static const float for this purpose.
    – Puppy
    Dec 28 '10 at 18:11










  • I bet you forgot to compare with 0? :)
    – user2771260
    Sep 12 '13 at 5:13








2




2




Might want to look at this stackoverflow.com/questions/17333/…
– Dr G
Dec 28 '10 at 17:40




Might want to look at this stackoverflow.com/questions/17333/…
– Dr G
Dec 28 '10 at 17:40




1




1




Depends on the use case, but what about very small numbers? Your code would compare 1e-10 and 1e-15 and -1e-10 as all equal. There is no single "correct" way to compare floating point numbers for "closeness".
– aschepler
Dec 28 '10 at 18:02




Depends on the use case, but what about very small numbers? Your code would compare 1e-10 and 1e-15 and -1e-10 as all equal. There is no single "correct" way to compare floating point numbers for "closeness".
– aschepler
Dec 28 '10 at 18:02




4




4




Why #define? You can just use a static const float for this purpose.
– Puppy
Dec 28 '10 at 18:11




Why #define? You can just use a static const float for this purpose.
– Puppy
Dec 28 '10 at 18:11












I bet you forgot to compare with 0? :)
– user2771260
Sep 12 '13 at 5:13




I bet you forgot to compare with 0? :)
– user2771260
Sep 12 '13 at 5:13












8 Answers
8






active

oldest

votes


















15














From The Floating-Point Guide:




This is a bad way to do it because a
fixed epsilon chosen because it “looks
small” could actually be way too large
when the numbers being compared are
very small as well. The comparison
would return “true” for numbers that
are quite different. And when the
numbers are very large, the epsilon
could end up being smaller than the
smallest rounding error, so that the
comparison always returns “false”.




The problem with the "magic number" here is not that it's hardcoded but that it's "magic": you didn't really have a reason for choosing 0.000001 over 0.000005 or 0.0000000000001, did you? Note that float can approximately represent the latter and still smaller values - it's just about 7 decimals of precision after the first nonzero digit!



If you're going to use a fixed epsilon, you should really choose it according to the requirements of the particular piece of code where you use it. The alternative is to use a relative error margin (see link at the top for details) or, even better, or compare the floats as integers.






share|improve this answer

















  • 2




    For what it's worth, Bruce Dawson has mentioned that his article on comparing floating-point numbers is now obsolete, and that readers should refer to the 2012 edition instead.
    – Chris Frederick
    Aug 28 '12 at 3:25












  • @Chris Frederick: thanks, I'll add a link to that edition to the website
    – Michael Borgwardt
    Aug 28 '12 at 8:14



















12














The Standard provides an epsilon value. It's in <limits> and you can access the value by std::numeric_limits<float>::epsilon and std::numeric_limits<double>::epsilon. There are other values in there, but I didn't check what exactly is.






share|improve this answer

















  • 6




    Although beware that epsilon is not a straight replacement for the constant tolerance as used by the questioner. It represents out-by-1 in the least significant bit of the value 1.0, so if your values are approximately 2, then it's too small to provide any tolerance. It's quite difficult to use effectively.
    – Steve Jessop
    Dec 28 '10 at 20:30





















7














You should be aware that if you are comparing two floats for equality, you
are intrinsically doing the wrong thing. Adding a slop factor to the comparison
is not good enough.






share|improve this answer





















  • Agree with @ddyer: OP needs to go and do a course on numerical analysis.
    – Yttrill
    Dec 28 '10 at 22:30










  • How about unit tests? If I'm testing an algorithm and I want to check that the result, with given input values, is close to the expected (float) value?
    – Gauthier
    Dec 5 '16 at 12:32










  • Good question, with no simple answer. If you're just checking for gross errors in the algorithm, then I suppose a slop factor is a good place to start. Other tests would involve feeding data designed to trigger problems, such as using 2^32-1 as an integer input. More generally, you'd probably plot the differences between your implementation and a reference standard, looking for evidence of divergence.
    – ddyer
    Dec 5 '16 at 17:41



















7














You can use std::nextafter for testing two double with the smallest epsilon on a value (or a factor of the smallest epsilon).



bool nearly_equal(double a, double b)
{
return std::nextafter(a, std::numeric_limits<double>::lowest()) <= b
&& std::nextafter(a, std::numeric_limits<double>::max()) >= b;
}

bool nearly_equal(double a, double b, int factor /* a factor of epsilon */)
{
double min_a = a - (a - std::nextafter(a, std::numeric_limits<double>::lowest())) * factor;
double max_a = a + (std::nextafter(a, std::numeric_limits<double>::max()) - a) * factor;

return min_a <= b && max_a >= b;
}





share|improve this answer































    4














    You should use the standard define in float.h:



    #define DBL_EPSILON     2.2204460492503131e-016 /* smallest float value such that 1.0+DBL_EPSILON != 1.0 */


    or the numeric_limits class:



    // excerpt
    template<>
    class numeric_limits<float> : public _Num_float_base
    {
    public:
    typedef float T;

    // return minimum value
    static T (min)() throw();

    // return smallest effective increment from 1.0
    static T epsilon() throw();

    // return largest rounding error
    static T round_error() throw();

    // return minimum denormalized value
    static T denorm_min() throw();
    };


    [EDIT: Made it just a little bit more readable.]



    But in addition, it depends on what you're after.






    share|improve this answer



















    • 2




      +1: nice, but a header copy-paste isn't the most helpful IMO.
      – rubenvb
      Dec 28 '10 at 19:40






    • 1




      I just want to show that there are more interesting values in the numeric_limits<float> implementation.
      – 0xbadf00d
      Dec 30 '10 at 16:00










    • Where did you get the comment “smallest float value such that 1.0+DBL_EPSILON != 1.0” from? This is the wrong phrase to define DBL_EPSILON. blog.frama-c.com/index.php?post/2013/05/09/FLT_EPSILON
      – Pascal Cuoq
      Jul 19 '13 at 7:31










    • I've got the comment from the implementation in Visual Studio 2012. Didn't think about until your post.
      – 0xbadf00d
      Aug 9 '13 at 17:37



















    3














    Thanks for your answers, they helped me a lot. I've read these materials:first and second



    The answer is to use my own function for relative comparison:



    bool areEqualRel(float a, float b, float epsilon) {
    return (fabs(a - b) <= epsilon * std::max(fabs(a), fabs(b)));
    }


    This is the most suitable solution for my needs. However I've wrote some tests and other comparison methods. I hope this will be useful for somebody. areEqualRel passes these tests, others don't.



    #include <iostream>
    #include <limits>
    #include <algorithm>

    using std::cout;
    using std::max;

    bool areEqualAbs(float a, float b, float epsilon) {
    return (fabs(a - b) <= epsilon);
    }

    bool areEqual(float a, float b, float epsilon) {
    return (fabs(a - b) <= epsilon * std::max(1.0f, std::max(a, b)));
    }

    bool areEqualRel(float a, float b, float epsilon) {
    return (fabs(a - b) <= epsilon * std::max(fabs(a), fabs(b)));
    }

    int main(int argc, char *argv)
    {
    cout << "minimum: " << FLT_MIN << "n";
    cout << "maximum: " << FLT_MAX << "n";
    cout << "epsilon: " << FLT_EPSILON << "n";

    float a = 0.0000001f;
    float b = 0.0000002f;
    if (areEqualRel(a, b, FLT_EPSILON)) {
    cout << "are equal a: " << a << " b: " << b << "n";
    }
    a = 1000001.f;
    b = 1000002.f;
    if (areEqualRel(a, b, FLT_EPSILON)) {
    cout << "are equal a: " << a << " b: " << b << "n";
    }
    }





    share|improve this answer



















    • 1




      Surely you mean std::max(fabs(a), fabs(b)), unless all your floats are positive
      – TonyK
      Jan 4 '11 at 22:09










    • I don't think this is needed here. If you have an example that areEqualRel() will fail please provide it. Or firstly test in the code above.
      – Dmitriy
      Jan 5 '11 at 7:53






    • 1




      How about a = b = -1000 ?
      – TonyK
      Jan 6 '11 at 13:55










    • Thanks TonyK, you're correct, I haven't time to write a complete unit test to see it. I've fixed areEqualRel in my post
      – Dmitriy
      Jan 16 '11 at 13:19





















    3














    Here is a c++11 implementation of @geotavros 's solution. It makes use of the new std::numeric_limits<T>::epsilon() function and the fact that std::fabs() and std::fmax() now have overloads for float, double and long float.



    template<typename T>
    static bool AreEqual(T f1, T f2) {
    return (std::fabs(f1 - f2) <= std::numeric_limits<T>::epsilon() * std::fmax(std::fabs(f1), std::fabs(f2)));
    }





    share|improve this answer































      1














      This post has a comprehensive explanation of how to compare floating point numbers:
      http://www.altdevblogaday.com/2012/02/22/comparing-floating-point-numbers-2012-edition/



      Excerpt:





      • If you are comparing against zero, then relative epsilons and ULPs based comparisons are usually meaningless. You’ll need to use an
        absolute epsilon, whose value might be some small multiple of
        FLT_EPSILON and the inputs to your calculation. Maybe.

      • If you are comparing against a non-zero number then relative epsilons or ULPs based comparisons are probably what you want. You’ll
        probably want some small multiple of FLT_EPSILON for your relative
        epsilon, or some small number of ULPs. An absolute epsilon could be
        used if you knew exactly what number you were comparing against.







      share|improve this answer





















        Your Answer






        StackExchange.ifUsing("editor", function () {
        StackExchange.using("externalEditor", function () {
        StackExchange.using("snippets", function () {
        StackExchange.snippets.init();
        });
        });
        }, "code-snippets");

        StackExchange.ready(function() {
        var channelOptions = {
        tags: "".split(" "),
        id: "1"
        };
        initTagRenderer("".split(" "), "".split(" "), channelOptions);

        StackExchange.using("externalEditor", function() {
        // Have to fire editor after snippets, if snippets enabled
        if (StackExchange.settings.snippets.snippetsEnabled) {
        StackExchange.using("snippets", function() {
        createEditor();
        });
        }
        else {
        createEditor();
        }
        });

        function createEditor() {
        StackExchange.prepareEditor({
        heartbeatType: 'answer',
        autoActivateHeartbeat: false,
        convertImagesToLinks: true,
        noModals: true,
        showLowRepImageUploadWarning: true,
        reputationToPostImages: 10,
        bindNavPrevention: true,
        postfix: "",
        imageUploader: {
        brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
        contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
        allowUrls: true
        },
        onDemand: true,
        discardSelector: ".discard-answer"
        ,immediatelyShowMarkdownHelp:true
        });


        }
        });














        draft saved

        draft discarded


















        StackExchange.ready(
        function () {
        StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f4548004%2fhow-to-correctly-and-standardly-compare-floats%23new-answer', 'question_page');
        }
        );

        Post as a guest















        Required, but never shown

























        8 Answers
        8






        active

        oldest

        votes








        8 Answers
        8






        active

        oldest

        votes









        active

        oldest

        votes






        active

        oldest

        votes









        15














        From The Floating-Point Guide:




        This is a bad way to do it because a
        fixed epsilon chosen because it “looks
        small” could actually be way too large
        when the numbers being compared are
        very small as well. The comparison
        would return “true” for numbers that
        are quite different. And when the
        numbers are very large, the epsilon
        could end up being smaller than the
        smallest rounding error, so that the
        comparison always returns “false”.




        The problem with the "magic number" here is not that it's hardcoded but that it's "magic": you didn't really have a reason for choosing 0.000001 over 0.000005 or 0.0000000000001, did you? Note that float can approximately represent the latter and still smaller values - it's just about 7 decimals of precision after the first nonzero digit!



        If you're going to use a fixed epsilon, you should really choose it according to the requirements of the particular piece of code where you use it. The alternative is to use a relative error margin (see link at the top for details) or, even better, or compare the floats as integers.






        share|improve this answer

















        • 2




          For what it's worth, Bruce Dawson has mentioned that his article on comparing floating-point numbers is now obsolete, and that readers should refer to the 2012 edition instead.
          – Chris Frederick
          Aug 28 '12 at 3:25












        • @Chris Frederick: thanks, I'll add a link to that edition to the website
          – Michael Borgwardt
          Aug 28 '12 at 8:14
















        15














        From The Floating-Point Guide:




        This is a bad way to do it because a
        fixed epsilon chosen because it “looks
        small” could actually be way too large
        when the numbers being compared are
        very small as well. The comparison
        would return “true” for numbers that
        are quite different. And when the
        numbers are very large, the epsilon
        could end up being smaller than the
        smallest rounding error, so that the
        comparison always returns “false”.




        The problem with the "magic number" here is not that it's hardcoded but that it's "magic": you didn't really have a reason for choosing 0.000001 over 0.000005 or 0.0000000000001, did you? Note that float can approximately represent the latter and still smaller values - it's just about 7 decimals of precision after the first nonzero digit!



        If you're going to use a fixed epsilon, you should really choose it according to the requirements of the particular piece of code where you use it. The alternative is to use a relative error margin (see link at the top for details) or, even better, or compare the floats as integers.






        share|improve this answer

















        • 2




          For what it's worth, Bruce Dawson has mentioned that his article on comparing floating-point numbers is now obsolete, and that readers should refer to the 2012 edition instead.
          – Chris Frederick
          Aug 28 '12 at 3:25












        • @Chris Frederick: thanks, I'll add a link to that edition to the website
          – Michael Borgwardt
          Aug 28 '12 at 8:14














        15












        15








        15






        From The Floating-Point Guide:




        This is a bad way to do it because a
        fixed epsilon chosen because it “looks
        small” could actually be way too large
        when the numbers being compared are
        very small as well. The comparison
        would return “true” for numbers that
        are quite different. And when the
        numbers are very large, the epsilon
        could end up being smaller than the
        smallest rounding error, so that the
        comparison always returns “false”.




        The problem with the "magic number" here is not that it's hardcoded but that it's "magic": you didn't really have a reason for choosing 0.000001 over 0.000005 or 0.0000000000001, did you? Note that float can approximately represent the latter and still smaller values - it's just about 7 decimals of precision after the first nonzero digit!



        If you're going to use a fixed epsilon, you should really choose it according to the requirements of the particular piece of code where you use it. The alternative is to use a relative error margin (see link at the top for details) or, even better, or compare the floats as integers.






        share|improve this answer












        From The Floating-Point Guide:




        This is a bad way to do it because a
        fixed epsilon chosen because it “looks
        small” could actually be way too large
        when the numbers being compared are
        very small as well. The comparison
        would return “true” for numbers that
        are quite different. And when the
        numbers are very large, the epsilon
        could end up being smaller than the
        smallest rounding error, so that the
        comparison always returns “false”.




        The problem with the "magic number" here is not that it's hardcoded but that it's "magic": you didn't really have a reason for choosing 0.000001 over 0.000005 or 0.0000000000001, did you? Note that float can approximately represent the latter and still smaller values - it's just about 7 decimals of precision after the first nonzero digit!



        If you're going to use a fixed epsilon, you should really choose it according to the requirements of the particular piece of code where you use it. The alternative is to use a relative error margin (see link at the top for details) or, even better, or compare the floats as integers.







        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered Dec 28 '10 at 19:50









        Michael Borgwardt

        293k63426662




        293k63426662








        • 2




          For what it's worth, Bruce Dawson has mentioned that his article on comparing floating-point numbers is now obsolete, and that readers should refer to the 2012 edition instead.
          – Chris Frederick
          Aug 28 '12 at 3:25












        • @Chris Frederick: thanks, I'll add a link to that edition to the website
          – Michael Borgwardt
          Aug 28 '12 at 8:14














        • 2




          For what it's worth, Bruce Dawson has mentioned that his article on comparing floating-point numbers is now obsolete, and that readers should refer to the 2012 edition instead.
          – Chris Frederick
          Aug 28 '12 at 3:25












        • @Chris Frederick: thanks, I'll add a link to that edition to the website
          – Michael Borgwardt
          Aug 28 '12 at 8:14








        2




        2




        For what it's worth, Bruce Dawson has mentioned that his article on comparing floating-point numbers is now obsolete, and that readers should refer to the 2012 edition instead.
        – Chris Frederick
        Aug 28 '12 at 3:25






        For what it's worth, Bruce Dawson has mentioned that his article on comparing floating-point numbers is now obsolete, and that readers should refer to the 2012 edition instead.
        – Chris Frederick
        Aug 28 '12 at 3:25














        @Chris Frederick: thanks, I'll add a link to that edition to the website
        – Michael Borgwardt
        Aug 28 '12 at 8:14




        @Chris Frederick: thanks, I'll add a link to that edition to the website
        – Michael Borgwardt
        Aug 28 '12 at 8:14













        12














        The Standard provides an epsilon value. It's in <limits> and you can access the value by std::numeric_limits<float>::epsilon and std::numeric_limits<double>::epsilon. There are other values in there, but I didn't check what exactly is.






        share|improve this answer

















        • 6




          Although beware that epsilon is not a straight replacement for the constant tolerance as used by the questioner. It represents out-by-1 in the least significant bit of the value 1.0, so if your values are approximately 2, then it's too small to provide any tolerance. It's quite difficult to use effectively.
          – Steve Jessop
          Dec 28 '10 at 20:30


















        12














        The Standard provides an epsilon value. It's in <limits> and you can access the value by std::numeric_limits<float>::epsilon and std::numeric_limits<double>::epsilon. There are other values in there, but I didn't check what exactly is.






        share|improve this answer

















        • 6




          Although beware that epsilon is not a straight replacement for the constant tolerance as used by the questioner. It represents out-by-1 in the least significant bit of the value 1.0, so if your values are approximately 2, then it's too small to provide any tolerance. It's quite difficult to use effectively.
          – Steve Jessop
          Dec 28 '10 at 20:30
















        12












        12








        12






        The Standard provides an epsilon value. It's in <limits> and you can access the value by std::numeric_limits<float>::epsilon and std::numeric_limits<double>::epsilon. There are other values in there, but I didn't check what exactly is.






        share|improve this answer












        The Standard provides an epsilon value. It's in <limits> and you can access the value by std::numeric_limits<float>::epsilon and std::numeric_limits<double>::epsilon. There are other values in there, but I didn't check what exactly is.







        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered Dec 28 '10 at 18:16









        Puppy

        123k25194405




        123k25194405








        • 6




          Although beware that epsilon is not a straight replacement for the constant tolerance as used by the questioner. It represents out-by-1 in the least significant bit of the value 1.0, so if your values are approximately 2, then it's too small to provide any tolerance. It's quite difficult to use effectively.
          – Steve Jessop
          Dec 28 '10 at 20:30
















        • 6




          Although beware that epsilon is not a straight replacement for the constant tolerance as used by the questioner. It represents out-by-1 in the least significant bit of the value 1.0, so if your values are approximately 2, then it's too small to provide any tolerance. It's quite difficult to use effectively.
          – Steve Jessop
          Dec 28 '10 at 20:30










        6




        6




        Although beware that epsilon is not a straight replacement for the constant tolerance as used by the questioner. It represents out-by-1 in the least significant bit of the value 1.0, so if your values are approximately 2, then it's too small to provide any tolerance. It's quite difficult to use effectively.
        – Steve Jessop
        Dec 28 '10 at 20:30






        Although beware that epsilon is not a straight replacement for the constant tolerance as used by the questioner. It represents out-by-1 in the least significant bit of the value 1.0, so if your values are approximately 2, then it's too small to provide any tolerance. It's quite difficult to use effectively.
        – Steve Jessop
        Dec 28 '10 at 20:30













        7














        You should be aware that if you are comparing two floats for equality, you
        are intrinsically doing the wrong thing. Adding a slop factor to the comparison
        is not good enough.






        share|improve this answer





















        • Agree with @ddyer: OP needs to go and do a course on numerical analysis.
          – Yttrill
          Dec 28 '10 at 22:30










        • How about unit tests? If I'm testing an algorithm and I want to check that the result, with given input values, is close to the expected (float) value?
          – Gauthier
          Dec 5 '16 at 12:32










        • Good question, with no simple answer. If you're just checking for gross errors in the algorithm, then I suppose a slop factor is a good place to start. Other tests would involve feeding data designed to trigger problems, such as using 2^32-1 as an integer input. More generally, you'd probably plot the differences between your implementation and a reference standard, looking for evidence of divergence.
          – ddyer
          Dec 5 '16 at 17:41
















        7














        You should be aware that if you are comparing two floats for equality, you
        are intrinsically doing the wrong thing. Adding a slop factor to the comparison
        is not good enough.






        share|improve this answer





















        • Agree with @ddyer: OP needs to go and do a course on numerical analysis.
          – Yttrill
          Dec 28 '10 at 22:30










        • How about unit tests? If I'm testing an algorithm and I want to check that the result, with given input values, is close to the expected (float) value?
          – Gauthier
          Dec 5 '16 at 12:32










        • Good question, with no simple answer. If you're just checking for gross errors in the algorithm, then I suppose a slop factor is a good place to start. Other tests would involve feeding data designed to trigger problems, such as using 2^32-1 as an integer input. More generally, you'd probably plot the differences between your implementation and a reference standard, looking for evidence of divergence.
          – ddyer
          Dec 5 '16 at 17:41














        7












        7








        7






        You should be aware that if you are comparing two floats for equality, you
        are intrinsically doing the wrong thing. Adding a slop factor to the comparison
        is not good enough.






        share|improve this answer












        You should be aware that if you are comparing two floats for equality, you
        are intrinsically doing the wrong thing. Adding a slop factor to the comparison
        is not good enough.







        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered Dec 28 '10 at 17:44









        ddyer

        1,8651621




        1,8651621












        • Agree with @ddyer: OP needs to go and do a course on numerical analysis.
          – Yttrill
          Dec 28 '10 at 22:30










        • How about unit tests? If I'm testing an algorithm and I want to check that the result, with given input values, is close to the expected (float) value?
          – Gauthier
          Dec 5 '16 at 12:32










        • Good question, with no simple answer. If you're just checking for gross errors in the algorithm, then I suppose a slop factor is a good place to start. Other tests would involve feeding data designed to trigger problems, such as using 2^32-1 as an integer input. More generally, you'd probably plot the differences between your implementation and a reference standard, looking for evidence of divergence.
          – ddyer
          Dec 5 '16 at 17:41


















        • Agree with @ddyer: OP needs to go and do a course on numerical analysis.
          – Yttrill
          Dec 28 '10 at 22:30










        • How about unit tests? If I'm testing an algorithm and I want to check that the result, with given input values, is close to the expected (float) value?
          – Gauthier
          Dec 5 '16 at 12:32










        • Good question, with no simple answer. If you're just checking for gross errors in the algorithm, then I suppose a slop factor is a good place to start. Other tests would involve feeding data designed to trigger problems, such as using 2^32-1 as an integer input. More generally, you'd probably plot the differences between your implementation and a reference standard, looking for evidence of divergence.
          – ddyer
          Dec 5 '16 at 17:41
















        Agree with @ddyer: OP needs to go and do a course on numerical analysis.
        – Yttrill
        Dec 28 '10 at 22:30




        Agree with @ddyer: OP needs to go and do a course on numerical analysis.
        – Yttrill
        Dec 28 '10 at 22:30












        How about unit tests? If I'm testing an algorithm and I want to check that the result, with given input values, is close to the expected (float) value?
        – Gauthier
        Dec 5 '16 at 12:32




        How about unit tests? If I'm testing an algorithm and I want to check that the result, with given input values, is close to the expected (float) value?
        – Gauthier
        Dec 5 '16 at 12:32












        Good question, with no simple answer. If you're just checking for gross errors in the algorithm, then I suppose a slop factor is a good place to start. Other tests would involve feeding data designed to trigger problems, such as using 2^32-1 as an integer input. More generally, you'd probably plot the differences between your implementation and a reference standard, looking for evidence of divergence.
        – ddyer
        Dec 5 '16 at 17:41




        Good question, with no simple answer. If you're just checking for gross errors in the algorithm, then I suppose a slop factor is a good place to start. Other tests would involve feeding data designed to trigger problems, such as using 2^32-1 as an integer input. More generally, you'd probably plot the differences between your implementation and a reference standard, looking for evidence of divergence.
        – ddyer
        Dec 5 '16 at 17:41











        7














        You can use std::nextafter for testing two double with the smallest epsilon on a value (or a factor of the smallest epsilon).



        bool nearly_equal(double a, double b)
        {
        return std::nextafter(a, std::numeric_limits<double>::lowest()) <= b
        && std::nextafter(a, std::numeric_limits<double>::max()) >= b;
        }

        bool nearly_equal(double a, double b, int factor /* a factor of epsilon */)
        {
        double min_a = a - (a - std::nextafter(a, std::numeric_limits<double>::lowest())) * factor;
        double max_a = a + (std::nextafter(a, std::numeric_limits<double>::max()) - a) * factor;

        return min_a <= b && max_a >= b;
        }





        share|improve this answer




























          7














          You can use std::nextafter for testing two double with the smallest epsilon on a value (or a factor of the smallest epsilon).



          bool nearly_equal(double a, double b)
          {
          return std::nextafter(a, std::numeric_limits<double>::lowest()) <= b
          && std::nextafter(a, std::numeric_limits<double>::max()) >= b;
          }

          bool nearly_equal(double a, double b, int factor /* a factor of epsilon */)
          {
          double min_a = a - (a - std::nextafter(a, std::numeric_limits<double>::lowest())) * factor;
          double max_a = a + (std::nextafter(a, std::numeric_limits<double>::max()) - a) * factor;

          return min_a <= b && max_a >= b;
          }





          share|improve this answer


























            7












            7








            7






            You can use std::nextafter for testing two double with the smallest epsilon on a value (or a factor of the smallest epsilon).



            bool nearly_equal(double a, double b)
            {
            return std::nextafter(a, std::numeric_limits<double>::lowest()) <= b
            && std::nextafter(a, std::numeric_limits<double>::max()) >= b;
            }

            bool nearly_equal(double a, double b, int factor /* a factor of epsilon */)
            {
            double min_a = a - (a - std::nextafter(a, std::numeric_limits<double>::lowest())) * factor;
            double max_a = a + (std::nextafter(a, std::numeric_limits<double>::max()) - a) * factor;

            return min_a <= b && max_a >= b;
            }





            share|improve this answer














            You can use std::nextafter for testing two double with the smallest epsilon on a value (or a factor of the smallest epsilon).



            bool nearly_equal(double a, double b)
            {
            return std::nextafter(a, std::numeric_limits<double>::lowest()) <= b
            && std::nextafter(a, std::numeric_limits<double>::max()) >= b;
            }

            bool nearly_equal(double a, double b, int factor /* a factor of epsilon */)
            {
            double min_a = a - (a - std::nextafter(a, std::numeric_limits<double>::lowest())) * factor;
            double max_a = a + (std::nextafter(a, std::numeric_limits<double>::max()) - a) * factor;

            return min_a <= b && max_a >= b;
            }






            share|improve this answer














            share|improve this answer



            share|improve this answer








            edited Feb 21 '16 at 14:38

























            answered Feb 7 '16 at 11:34









            Daniel Laügt

            614713




            614713























                4














                You should use the standard define in float.h:



                #define DBL_EPSILON     2.2204460492503131e-016 /* smallest float value such that 1.0+DBL_EPSILON != 1.0 */


                or the numeric_limits class:



                // excerpt
                template<>
                class numeric_limits<float> : public _Num_float_base
                {
                public:
                typedef float T;

                // return minimum value
                static T (min)() throw();

                // return smallest effective increment from 1.0
                static T epsilon() throw();

                // return largest rounding error
                static T round_error() throw();

                // return minimum denormalized value
                static T denorm_min() throw();
                };


                [EDIT: Made it just a little bit more readable.]



                But in addition, it depends on what you're after.






                share|improve this answer



















                • 2




                  +1: nice, but a header copy-paste isn't the most helpful IMO.
                  – rubenvb
                  Dec 28 '10 at 19:40






                • 1




                  I just want to show that there are more interesting values in the numeric_limits<float> implementation.
                  – 0xbadf00d
                  Dec 30 '10 at 16:00










                • Where did you get the comment “smallest float value such that 1.0+DBL_EPSILON != 1.0” from? This is the wrong phrase to define DBL_EPSILON. blog.frama-c.com/index.php?post/2013/05/09/FLT_EPSILON
                  – Pascal Cuoq
                  Jul 19 '13 at 7:31










                • I've got the comment from the implementation in Visual Studio 2012. Didn't think about until your post.
                  – 0xbadf00d
                  Aug 9 '13 at 17:37
















                4














                You should use the standard define in float.h:



                #define DBL_EPSILON     2.2204460492503131e-016 /* smallest float value such that 1.0+DBL_EPSILON != 1.0 */


                or the numeric_limits class:



                // excerpt
                template<>
                class numeric_limits<float> : public _Num_float_base
                {
                public:
                typedef float T;

                // return minimum value
                static T (min)() throw();

                // return smallest effective increment from 1.0
                static T epsilon() throw();

                // return largest rounding error
                static T round_error() throw();

                // return minimum denormalized value
                static T denorm_min() throw();
                };


                [EDIT: Made it just a little bit more readable.]



                But in addition, it depends on what you're after.






                share|improve this answer



















                • 2




                  +1: nice, but a header copy-paste isn't the most helpful IMO.
                  – rubenvb
                  Dec 28 '10 at 19:40






                • 1




                  I just want to show that there are more interesting values in the numeric_limits<float> implementation.
                  – 0xbadf00d
                  Dec 30 '10 at 16:00










                • Where did you get the comment “smallest float value such that 1.0+DBL_EPSILON != 1.0” from? This is the wrong phrase to define DBL_EPSILON. blog.frama-c.com/index.php?post/2013/05/09/FLT_EPSILON
                  – Pascal Cuoq
                  Jul 19 '13 at 7:31










                • I've got the comment from the implementation in Visual Studio 2012. Didn't think about until your post.
                  – 0xbadf00d
                  Aug 9 '13 at 17:37














                4












                4








                4






                You should use the standard define in float.h:



                #define DBL_EPSILON     2.2204460492503131e-016 /* smallest float value such that 1.0+DBL_EPSILON != 1.0 */


                or the numeric_limits class:



                // excerpt
                template<>
                class numeric_limits<float> : public _Num_float_base
                {
                public:
                typedef float T;

                // return minimum value
                static T (min)() throw();

                // return smallest effective increment from 1.0
                static T epsilon() throw();

                // return largest rounding error
                static T round_error() throw();

                // return minimum denormalized value
                static T denorm_min() throw();
                };


                [EDIT: Made it just a little bit more readable.]



                But in addition, it depends on what you're after.






                share|improve this answer














                You should use the standard define in float.h:



                #define DBL_EPSILON     2.2204460492503131e-016 /* smallest float value such that 1.0+DBL_EPSILON != 1.0 */


                or the numeric_limits class:



                // excerpt
                template<>
                class numeric_limits<float> : public _Num_float_base
                {
                public:
                typedef float T;

                // return minimum value
                static T (min)() throw();

                // return smallest effective increment from 1.0
                static T epsilon() throw();

                // return largest rounding error
                static T round_error() throw();

                // return minimum denormalized value
                static T denorm_min() throw();
                };


                [EDIT: Made it just a little bit more readable.]



                But in addition, it depends on what you're after.







                share|improve this answer














                share|improve this answer



                share|improve this answer








                edited Dec 30 '10 at 16:26

























                answered Dec 28 '10 at 18:30









                0xbadf00d

                6,009145182




                6,009145182








                • 2




                  +1: nice, but a header copy-paste isn't the most helpful IMO.
                  – rubenvb
                  Dec 28 '10 at 19:40






                • 1




                  I just want to show that there are more interesting values in the numeric_limits<float> implementation.
                  – 0xbadf00d
                  Dec 30 '10 at 16:00










                • Where did you get the comment “smallest float value such that 1.0+DBL_EPSILON != 1.0” from? This is the wrong phrase to define DBL_EPSILON. blog.frama-c.com/index.php?post/2013/05/09/FLT_EPSILON
                  – Pascal Cuoq
                  Jul 19 '13 at 7:31










                • I've got the comment from the implementation in Visual Studio 2012. Didn't think about until your post.
                  – 0xbadf00d
                  Aug 9 '13 at 17:37














                • 2




                  +1: nice, but a header copy-paste isn't the most helpful IMO.
                  – rubenvb
                  Dec 28 '10 at 19:40






                • 1




                  I just want to show that there are more interesting values in the numeric_limits<float> implementation.
                  – 0xbadf00d
                  Dec 30 '10 at 16:00










                • Where did you get the comment “smallest float value such that 1.0+DBL_EPSILON != 1.0” from? This is the wrong phrase to define DBL_EPSILON. blog.frama-c.com/index.php?post/2013/05/09/FLT_EPSILON
                  – Pascal Cuoq
                  Jul 19 '13 at 7:31










                • I've got the comment from the implementation in Visual Studio 2012. Didn't think about until your post.
                  – 0xbadf00d
                  Aug 9 '13 at 17:37








                2




                2




                +1: nice, but a header copy-paste isn't the most helpful IMO.
                – rubenvb
                Dec 28 '10 at 19:40




                +1: nice, but a header copy-paste isn't the most helpful IMO.
                – rubenvb
                Dec 28 '10 at 19:40




                1




                1




                I just want to show that there are more interesting values in the numeric_limits<float> implementation.
                – 0xbadf00d
                Dec 30 '10 at 16:00




                I just want to show that there are more interesting values in the numeric_limits<float> implementation.
                – 0xbadf00d
                Dec 30 '10 at 16:00












                Where did you get the comment “smallest float value such that 1.0+DBL_EPSILON != 1.0” from? This is the wrong phrase to define DBL_EPSILON. blog.frama-c.com/index.php?post/2013/05/09/FLT_EPSILON
                – Pascal Cuoq
                Jul 19 '13 at 7:31




                Where did you get the comment “smallest float value such that 1.0+DBL_EPSILON != 1.0” from? This is the wrong phrase to define DBL_EPSILON. blog.frama-c.com/index.php?post/2013/05/09/FLT_EPSILON
                – Pascal Cuoq
                Jul 19 '13 at 7:31












                I've got the comment from the implementation in Visual Studio 2012. Didn't think about until your post.
                – 0xbadf00d
                Aug 9 '13 at 17:37




                I've got the comment from the implementation in Visual Studio 2012. Didn't think about until your post.
                – 0xbadf00d
                Aug 9 '13 at 17:37











                3














                Thanks for your answers, they helped me a lot. I've read these materials:first and second



                The answer is to use my own function for relative comparison:



                bool areEqualRel(float a, float b, float epsilon) {
                return (fabs(a - b) <= epsilon * std::max(fabs(a), fabs(b)));
                }


                This is the most suitable solution for my needs. However I've wrote some tests and other comparison methods. I hope this will be useful for somebody. areEqualRel passes these tests, others don't.



                #include <iostream>
                #include <limits>
                #include <algorithm>

                using std::cout;
                using std::max;

                bool areEqualAbs(float a, float b, float epsilon) {
                return (fabs(a - b) <= epsilon);
                }

                bool areEqual(float a, float b, float epsilon) {
                return (fabs(a - b) <= epsilon * std::max(1.0f, std::max(a, b)));
                }

                bool areEqualRel(float a, float b, float epsilon) {
                return (fabs(a - b) <= epsilon * std::max(fabs(a), fabs(b)));
                }

                int main(int argc, char *argv)
                {
                cout << "minimum: " << FLT_MIN << "n";
                cout << "maximum: " << FLT_MAX << "n";
                cout << "epsilon: " << FLT_EPSILON << "n";

                float a = 0.0000001f;
                float b = 0.0000002f;
                if (areEqualRel(a, b, FLT_EPSILON)) {
                cout << "are equal a: " << a << " b: " << b << "n";
                }
                a = 1000001.f;
                b = 1000002.f;
                if (areEqualRel(a, b, FLT_EPSILON)) {
                cout << "are equal a: " << a << " b: " << b << "n";
                }
                }





                share|improve this answer



















                • 1




                  Surely you mean std::max(fabs(a), fabs(b)), unless all your floats are positive
                  – TonyK
                  Jan 4 '11 at 22:09










                • I don't think this is needed here. If you have an example that areEqualRel() will fail please provide it. Or firstly test in the code above.
                  – Dmitriy
                  Jan 5 '11 at 7:53






                • 1




                  How about a = b = -1000 ?
                  – TonyK
                  Jan 6 '11 at 13:55










                • Thanks TonyK, you're correct, I haven't time to write a complete unit test to see it. I've fixed areEqualRel in my post
                  – Dmitriy
                  Jan 16 '11 at 13:19


















                3














                Thanks for your answers, they helped me a lot. I've read these materials:first and second



                The answer is to use my own function for relative comparison:



                bool areEqualRel(float a, float b, float epsilon) {
                return (fabs(a - b) <= epsilon * std::max(fabs(a), fabs(b)));
                }


                This is the most suitable solution for my needs. However I've wrote some tests and other comparison methods. I hope this will be useful for somebody. areEqualRel passes these tests, others don't.



                #include <iostream>
                #include <limits>
                #include <algorithm>

                using std::cout;
                using std::max;

                bool areEqualAbs(float a, float b, float epsilon) {
                return (fabs(a - b) <= epsilon);
                }

                bool areEqual(float a, float b, float epsilon) {
                return (fabs(a - b) <= epsilon * std::max(1.0f, std::max(a, b)));
                }

                bool areEqualRel(float a, float b, float epsilon) {
                return (fabs(a - b) <= epsilon * std::max(fabs(a), fabs(b)));
                }

                int main(int argc, char *argv)
                {
                cout << "minimum: " << FLT_MIN << "n";
                cout << "maximum: " << FLT_MAX << "n";
                cout << "epsilon: " << FLT_EPSILON << "n";

                float a = 0.0000001f;
                float b = 0.0000002f;
                if (areEqualRel(a, b, FLT_EPSILON)) {
                cout << "are equal a: " << a << " b: " << b << "n";
                }
                a = 1000001.f;
                b = 1000002.f;
                if (areEqualRel(a, b, FLT_EPSILON)) {
                cout << "are equal a: " << a << " b: " << b << "n";
                }
                }





                share|improve this answer



















                • 1




                  Surely you mean std::max(fabs(a), fabs(b)), unless all your floats are positive
                  – TonyK
                  Jan 4 '11 at 22:09










                • I don't think this is needed here. If you have an example that areEqualRel() will fail please provide it. Or firstly test in the code above.
                  – Dmitriy
                  Jan 5 '11 at 7:53






                • 1




                  How about a = b = -1000 ?
                  – TonyK
                  Jan 6 '11 at 13:55










                • Thanks TonyK, you're correct, I haven't time to write a complete unit test to see it. I've fixed areEqualRel in my post
                  – Dmitriy
                  Jan 16 '11 at 13:19
















                3












                3








                3






                Thanks for your answers, they helped me a lot. I've read these materials:first and second



                The answer is to use my own function for relative comparison:



                bool areEqualRel(float a, float b, float epsilon) {
                return (fabs(a - b) <= epsilon * std::max(fabs(a), fabs(b)));
                }


                This is the most suitable solution for my needs. However I've wrote some tests and other comparison methods. I hope this will be useful for somebody. areEqualRel passes these tests, others don't.



                #include <iostream>
                #include <limits>
                #include <algorithm>

                using std::cout;
                using std::max;

                bool areEqualAbs(float a, float b, float epsilon) {
                return (fabs(a - b) <= epsilon);
                }

                bool areEqual(float a, float b, float epsilon) {
                return (fabs(a - b) <= epsilon * std::max(1.0f, std::max(a, b)));
                }

                bool areEqualRel(float a, float b, float epsilon) {
                return (fabs(a - b) <= epsilon * std::max(fabs(a), fabs(b)));
                }

                int main(int argc, char *argv)
                {
                cout << "minimum: " << FLT_MIN << "n";
                cout << "maximum: " << FLT_MAX << "n";
                cout << "epsilon: " << FLT_EPSILON << "n";

                float a = 0.0000001f;
                float b = 0.0000002f;
                if (areEqualRel(a, b, FLT_EPSILON)) {
                cout << "are equal a: " << a << " b: " << b << "n";
                }
                a = 1000001.f;
                b = 1000002.f;
                if (areEqualRel(a, b, FLT_EPSILON)) {
                cout << "are equal a: " << a << " b: " << b << "n";
                }
                }





                share|improve this answer














                Thanks for your answers, they helped me a lot. I've read these materials:first and second



                The answer is to use my own function for relative comparison:



                bool areEqualRel(float a, float b, float epsilon) {
                return (fabs(a - b) <= epsilon * std::max(fabs(a), fabs(b)));
                }


                This is the most suitable solution for my needs. However I've wrote some tests and other comparison methods. I hope this will be useful for somebody. areEqualRel passes these tests, others don't.



                #include <iostream>
                #include <limits>
                #include <algorithm>

                using std::cout;
                using std::max;

                bool areEqualAbs(float a, float b, float epsilon) {
                return (fabs(a - b) <= epsilon);
                }

                bool areEqual(float a, float b, float epsilon) {
                return (fabs(a - b) <= epsilon * std::max(1.0f, std::max(a, b)));
                }

                bool areEqualRel(float a, float b, float epsilon) {
                return (fabs(a - b) <= epsilon * std::max(fabs(a), fabs(b)));
                }

                int main(int argc, char *argv)
                {
                cout << "minimum: " << FLT_MIN << "n";
                cout << "maximum: " << FLT_MAX << "n";
                cout << "epsilon: " << FLT_EPSILON << "n";

                float a = 0.0000001f;
                float b = 0.0000002f;
                if (areEqualRel(a, b, FLT_EPSILON)) {
                cout << "are equal a: " << a << " b: " << b << "n";
                }
                a = 1000001.f;
                b = 1000002.f;
                if (areEqualRel(a, b, FLT_EPSILON)) {
                cout << "are equal a: " << a << " b: " << b << "n";
                }
                }






                share|improve this answer














                share|improve this answer



                share|improve this answer








                edited May 23 '17 at 11:55









                Community

                11




                11










                answered Jan 4 '11 at 21:56









                Dmitriy

                2,88253452




                2,88253452








                • 1




                  Surely you mean std::max(fabs(a), fabs(b)), unless all your floats are positive
                  – TonyK
                  Jan 4 '11 at 22:09










                • I don't think this is needed here. If you have an example that areEqualRel() will fail please provide it. Or firstly test in the code above.
                  – Dmitriy
                  Jan 5 '11 at 7:53






                • 1




                  How about a = b = -1000 ?
                  – TonyK
                  Jan 6 '11 at 13:55










                • Thanks TonyK, you're correct, I haven't time to write a complete unit test to see it. I've fixed areEqualRel in my post
                  – Dmitriy
                  Jan 16 '11 at 13:19
















                • 1




                  Surely you mean std::max(fabs(a), fabs(b)), unless all your floats are positive
                  – TonyK
                  Jan 4 '11 at 22:09










                • I don't think this is needed here. If you have an example that areEqualRel() will fail please provide it. Or firstly test in the code above.
                  – Dmitriy
                  Jan 5 '11 at 7:53






                • 1




                  How about a = b = -1000 ?
                  – TonyK
                  Jan 6 '11 at 13:55










                • Thanks TonyK, you're correct, I haven't time to write a complete unit test to see it. I've fixed areEqualRel in my post
                  – Dmitriy
                  Jan 16 '11 at 13:19










                1




                1




                Surely you mean std::max(fabs(a), fabs(b)), unless all your floats are positive
                – TonyK
                Jan 4 '11 at 22:09




                Surely you mean std::max(fabs(a), fabs(b)), unless all your floats are positive
                – TonyK
                Jan 4 '11 at 22:09












                I don't think this is needed here. If you have an example that areEqualRel() will fail please provide it. Or firstly test in the code above.
                – Dmitriy
                Jan 5 '11 at 7:53




                I don't think this is needed here. If you have an example that areEqualRel() will fail please provide it. Or firstly test in the code above.
                – Dmitriy
                Jan 5 '11 at 7:53




                1




                1




                How about a = b = -1000 ?
                – TonyK
                Jan 6 '11 at 13:55




                How about a = b = -1000 ?
                – TonyK
                Jan 6 '11 at 13:55












                Thanks TonyK, you're correct, I haven't time to write a complete unit test to see it. I've fixed areEqualRel in my post
                – Dmitriy
                Jan 16 '11 at 13:19






                Thanks TonyK, you're correct, I haven't time to write a complete unit test to see it. I've fixed areEqualRel in my post
                – Dmitriy
                Jan 16 '11 at 13:19













                3














                Here is a c++11 implementation of @geotavros 's solution. It makes use of the new std::numeric_limits<T>::epsilon() function and the fact that std::fabs() and std::fmax() now have overloads for float, double and long float.



                template<typename T>
                static bool AreEqual(T f1, T f2) {
                return (std::fabs(f1 - f2) <= std::numeric_limits<T>::epsilon() * std::fmax(std::fabs(f1), std::fabs(f2)));
                }





                share|improve this answer




























                  3














                  Here is a c++11 implementation of @geotavros 's solution. It makes use of the new std::numeric_limits<T>::epsilon() function and the fact that std::fabs() and std::fmax() now have overloads for float, double and long float.



                  template<typename T>
                  static bool AreEqual(T f1, T f2) {
                  return (std::fabs(f1 - f2) <= std::numeric_limits<T>::epsilon() * std::fmax(std::fabs(f1), std::fabs(f2)));
                  }





                  share|improve this answer


























                    3












                    3








                    3






                    Here is a c++11 implementation of @geotavros 's solution. It makes use of the new std::numeric_limits<T>::epsilon() function and the fact that std::fabs() and std::fmax() now have overloads for float, double and long float.



                    template<typename T>
                    static bool AreEqual(T f1, T f2) {
                    return (std::fabs(f1 - f2) <= std::numeric_limits<T>::epsilon() * std::fmax(std::fabs(f1), std::fabs(f2)));
                    }





                    share|improve this answer














                    Here is a c++11 implementation of @geotavros 's solution. It makes use of the new std::numeric_limits<T>::epsilon() function and the fact that std::fabs() and std::fmax() now have overloads for float, double and long float.



                    template<typename T>
                    static bool AreEqual(T f1, T f2) {
                    return (std::fabs(f1 - f2) <= std::numeric_limits<T>::epsilon() * std::fmax(std::fabs(f1), std::fabs(f2)));
                    }






                    share|improve this answer














                    share|improve this answer



                    share|improve this answer








                    edited Nov 12 '18 at 5:00









                    antb52

                    1625




                    1625










                    answered Oct 14 '16 at 9:11









                    Jelle van Campen

                    1734




                    1734























                        1














                        This post has a comprehensive explanation of how to compare floating point numbers:
                        http://www.altdevblogaday.com/2012/02/22/comparing-floating-point-numbers-2012-edition/



                        Excerpt:





                        • If you are comparing against zero, then relative epsilons and ULPs based comparisons are usually meaningless. You’ll need to use an
                          absolute epsilon, whose value might be some small multiple of
                          FLT_EPSILON and the inputs to your calculation. Maybe.

                        • If you are comparing against a non-zero number then relative epsilons or ULPs based comparisons are probably what you want. You’ll
                          probably want some small multiple of FLT_EPSILON for your relative
                          epsilon, or some small number of ULPs. An absolute epsilon could be
                          used if you knew exactly what number you were comparing against.







                        share|improve this answer


























                          1














                          This post has a comprehensive explanation of how to compare floating point numbers:
                          http://www.altdevblogaday.com/2012/02/22/comparing-floating-point-numbers-2012-edition/



                          Excerpt:





                          • If you are comparing against zero, then relative epsilons and ULPs based comparisons are usually meaningless. You’ll need to use an
                            absolute epsilon, whose value might be some small multiple of
                            FLT_EPSILON and the inputs to your calculation. Maybe.

                          • If you are comparing against a non-zero number then relative epsilons or ULPs based comparisons are probably what you want. You’ll
                            probably want some small multiple of FLT_EPSILON for your relative
                            epsilon, or some small number of ULPs. An absolute epsilon could be
                            used if you knew exactly what number you were comparing against.







                          share|improve this answer
























                            1












                            1








                            1






                            This post has a comprehensive explanation of how to compare floating point numbers:
                            http://www.altdevblogaday.com/2012/02/22/comparing-floating-point-numbers-2012-edition/



                            Excerpt:





                            • If you are comparing against zero, then relative epsilons and ULPs based comparisons are usually meaningless. You’ll need to use an
                              absolute epsilon, whose value might be some small multiple of
                              FLT_EPSILON and the inputs to your calculation. Maybe.

                            • If you are comparing against a non-zero number then relative epsilons or ULPs based comparisons are probably what you want. You’ll
                              probably want some small multiple of FLT_EPSILON for your relative
                              epsilon, or some small number of ULPs. An absolute epsilon could be
                              used if you knew exactly what number you were comparing against.







                            share|improve this answer












                            This post has a comprehensive explanation of how to compare floating point numbers:
                            http://www.altdevblogaday.com/2012/02/22/comparing-floating-point-numbers-2012-edition/



                            Excerpt:





                            • If you are comparing against zero, then relative epsilons and ULPs based comparisons are usually meaningless. You’ll need to use an
                              absolute epsilon, whose value might be some small multiple of
                              FLT_EPSILON and the inputs to your calculation. Maybe.

                            • If you are comparing against a non-zero number then relative epsilons or ULPs based comparisons are probably what you want. You’ll
                              probably want some small multiple of FLT_EPSILON for your relative
                              epsilon, or some small number of ULPs. An absolute epsilon could be
                              used if you knew exactly what number you were comparing against.








                            share|improve this answer












                            share|improve this answer



                            share|improve this answer










                            answered Jul 19 '13 at 5:00









                            blufiro

                            18519




                            18519






























                                draft saved

                                draft discarded




















































                                Thanks for contributing an answer to Stack Overflow!


                                • Please be sure to answer the question. Provide details and share your research!

                                But avoid



                                • Asking for help, clarification, or responding to other answers.

                                • Making statements based on opinion; back them up with references or personal experience.


                                To learn more, see our tips on writing great answers.





                                Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


                                Please pay close attention to the following guidance:


                                • Please be sure to answer the question. Provide details and share your research!

                                But avoid



                                • Asking for help, clarification, or responding to other answers.

                                • Making statements based on opinion; back them up with references or personal experience.


                                To learn more, see our tips on writing great answers.




                                draft saved


                                draft discarded














                                StackExchange.ready(
                                function () {
                                StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f4548004%2fhow-to-correctly-and-standardly-compare-floats%23new-answer', 'question_page');
                                }
                                );

                                Post as a guest















                                Required, but never shown





















































                                Required, but never shown














                                Required, but never shown












                                Required, but never shown







                                Required, but never shown

































                                Required, but never shown














                                Required, but never shown












                                Required, but never shown







                                Required, but never shown







                                這個網誌中的熱門文章

                                Tangent Lines Diagram Along Smooth Curve

                                Yusuf al-Mu'taman ibn Hud

                                Zucchini