Is binary equality comparison of floats correct?

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP












28















I'm working on different memory block manipulation functions and during benchmarks I noticed, that my implementation of the IsEqualRange(double* begin1, double* end1, double* begin2, double* end2) is much faster then the std::equals(...) on MSVC and GCC as well. Further investigation showed, that doubles and floats are not block compared by memcmp, but in a for loop one by one.



In what situation does binary comparison of floats lead to incorrect result? When is it ok to binary compare (equality) array of floats/doubles? Are there other fundamental types where I shouldn't use memcmp?










share|improve this question

















  • 1





    Related: stackoverflow.com/questions/25808445/…

    – DeiDei
    Jan 3 at 10:49






  • 1





    This answer to a related question is relevant to yours

    – Basile Starynkevitch
    Jan 3 at 10:52






  • 3





    @BasileStarynkevitch That is related to the nature of the floating points where not every number can be represented. Doesn't say much about the equality in binary form.

    – Zoltan Tirinda
    Jan 3 at 10:57






  • 2





    Similar: stackoverflow.com/q/8044862/560648

    – Lightness Races in Orbit
    Jan 3 at 11:25











  • @ZoltanTirinda But this affect equality because any non trivial calculation will encounter this not representable numbers during processing and this will affect final result. Every time someone use == then is good to mention this that it will not always do what you want (because of previous operations). You can know this but for other do not.

    – Yankes
    Jan 3 at 12:15















28















I'm working on different memory block manipulation functions and during benchmarks I noticed, that my implementation of the IsEqualRange(double* begin1, double* end1, double* begin2, double* end2) is much faster then the std::equals(...) on MSVC and GCC as well. Further investigation showed, that doubles and floats are not block compared by memcmp, but in a for loop one by one.



In what situation does binary comparison of floats lead to incorrect result? When is it ok to binary compare (equality) array of floats/doubles? Are there other fundamental types where I shouldn't use memcmp?










share|improve this question

















  • 1





    Related: stackoverflow.com/questions/25808445/…

    – DeiDei
    Jan 3 at 10:49






  • 1





    This answer to a related question is relevant to yours

    – Basile Starynkevitch
    Jan 3 at 10:52






  • 3





    @BasileStarynkevitch That is related to the nature of the floating points where not every number can be represented. Doesn't say much about the equality in binary form.

    – Zoltan Tirinda
    Jan 3 at 10:57






  • 2





    Similar: stackoverflow.com/q/8044862/560648

    – Lightness Races in Orbit
    Jan 3 at 11:25











  • @ZoltanTirinda But this affect equality because any non trivial calculation will encounter this not representable numbers during processing and this will affect final result. Every time someone use == then is good to mention this that it will not always do what you want (because of previous operations). You can know this but for other do not.

    – Yankes
    Jan 3 at 12:15













28












28








28


2






I'm working on different memory block manipulation functions and during benchmarks I noticed, that my implementation of the IsEqualRange(double* begin1, double* end1, double* begin2, double* end2) is much faster then the std::equals(...) on MSVC and GCC as well. Further investigation showed, that doubles and floats are not block compared by memcmp, but in a for loop one by one.



In what situation does binary comparison of floats lead to incorrect result? When is it ok to binary compare (equality) array of floats/doubles? Are there other fundamental types where I shouldn't use memcmp?










share|improve this question














I'm working on different memory block manipulation functions and during benchmarks I noticed, that my implementation of the IsEqualRange(double* begin1, double* end1, double* begin2, double* end2) is much faster then the std::equals(...) on MSVC and GCC as well. Further investigation showed, that doubles and floats are not block compared by memcmp, but in a for loop one by one.



In what situation does binary comparison of floats lead to incorrect result? When is it ok to binary compare (equality) array of floats/doubles? Are there other fundamental types where I shouldn't use memcmp?







c++ floating-point std






share|improve this question













share|improve this question











share|improve this question




share|improve this question










asked Jan 3 at 10:46









Zoltan TirindaZoltan Tirinda

469721




469721







  • 1





    Related: stackoverflow.com/questions/25808445/…

    – DeiDei
    Jan 3 at 10:49






  • 1





    This answer to a related question is relevant to yours

    – Basile Starynkevitch
    Jan 3 at 10:52






  • 3





    @BasileStarynkevitch That is related to the nature of the floating points where not every number can be represented. Doesn't say much about the equality in binary form.

    – Zoltan Tirinda
    Jan 3 at 10:57






  • 2





    Similar: stackoverflow.com/q/8044862/560648

    – Lightness Races in Orbit
    Jan 3 at 11:25











  • @ZoltanTirinda But this affect equality because any non trivial calculation will encounter this not representable numbers during processing and this will affect final result. Every time someone use == then is good to mention this that it will not always do what you want (because of previous operations). You can know this but for other do not.

    – Yankes
    Jan 3 at 12:15












  • 1





    Related: stackoverflow.com/questions/25808445/…

    – DeiDei
    Jan 3 at 10:49






  • 1





    This answer to a related question is relevant to yours

    – Basile Starynkevitch
    Jan 3 at 10:52






  • 3





    @BasileStarynkevitch That is related to the nature of the floating points where not every number can be represented. Doesn't say much about the equality in binary form.

    – Zoltan Tirinda
    Jan 3 at 10:57






  • 2





    Similar: stackoverflow.com/q/8044862/560648

    – Lightness Races in Orbit
    Jan 3 at 11:25











  • @ZoltanTirinda But this affect equality because any non trivial calculation will encounter this not representable numbers during processing and this will affect final result. Every time someone use == then is good to mention this that it will not always do what you want (because of previous operations). You can know this but for other do not.

    – Yankes
    Jan 3 at 12:15







1




1





Related: stackoverflow.com/questions/25808445/…

– DeiDei
Jan 3 at 10:49





Related: stackoverflow.com/questions/25808445/…

– DeiDei
Jan 3 at 10:49




1




1





This answer to a related question is relevant to yours

– Basile Starynkevitch
Jan 3 at 10:52





This answer to a related question is relevant to yours

– Basile Starynkevitch
Jan 3 at 10:52




3




3





@BasileStarynkevitch That is related to the nature of the floating points where not every number can be represented. Doesn't say much about the equality in binary form.

– Zoltan Tirinda
Jan 3 at 10:57





@BasileStarynkevitch That is related to the nature of the floating points where not every number can be represented. Doesn't say much about the equality in binary form.

– Zoltan Tirinda
Jan 3 at 10:57




2




2





Similar: stackoverflow.com/q/8044862/560648

– Lightness Races in Orbit
Jan 3 at 11:25





Similar: stackoverflow.com/q/8044862/560648

– Lightness Races in Orbit
Jan 3 at 11:25













@ZoltanTirinda But this affect equality because any non trivial calculation will encounter this not representable numbers during processing and this will affect final result. Every time someone use == then is good to mention this that it will not always do what you want (because of previous operations). You can know this but for other do not.

– Yankes
Jan 3 at 12:15





@ZoltanTirinda But this affect equality because any non trivial calculation will encounter this not representable numbers during processing and this will affect final result. Every time someone use == then is good to mention this that it will not always do what you want (because of previous operations). You can know this but for other do not.

– Yankes
Jan 3 at 12:15












3 Answers
3






active

oldest

votes


















49














The first thing I would do if I were you is to check your optimisation settings.



It's fine to use memcmp for an array of floating points but note that you could get different results to element-by-element ==. In particular, for IEEE754 floating point:



  1. +0.0 is defined to compare equal to -0.0.


  2. NaN is defined to compare not-equal to NaN.






share|improve this answer




















  • 3





    Also note that, technically, the C and C++ standards do not require the use of IEEE 754 to implement float and double. Most "reasonable" (modern) platforms will do so in practice, of course. But if you're uncertain that IEEE 754 is in use, then you have very few guarantees of how the == operator will behave on arbitrary bit patterns. A "weird" architecture could for example decide that ((float)0x00000000) == ((float)0x12345678), but memcmp will obviously consider those bytes different.

    – Kevin
    Jan 4 at 1:25











  • @Kevin: Indeed you're correct and I've narrowed the answer. I wonder if you fancy answering this question in more detail yourself; it seems to have attracted a lot of attention?

    – Bathsheba
    Jan 4 at 8:18











  • Thanks for the vote of confidence, but I don't really think I can add much to your answer as it now stands.

    – Kevin
    Jan 4 at 14:18


















14














The main issue is nan values, as these are never equal to themselves. There is also two representations of 0 (+0 and -0) that are equal but not binary equal.



So strictly speaking, you cannot use memcmp for them, as the answer would be mathematically incorrect.



If you know that you don't have nan or 0 values, then you can use memcmp.






share|improve this answer




















  • 5





    Zero has two representations in IEEE-754 binary floating-point, denoted as −0 and +0. They represent the same mathematical value and should be reported as equal, which == does but memcmp does not.

    – Eric Postpischil
    Jan 3 at 13:10






  • 1





    Yes indeed, that's why I said the main issue, of course, there is 0 as well.

    – Matthieu Brucher
    Jan 3 at 13:30






  • 1





    There's another way to get two numbers that compare numerically equal but not binary equal: if a denormalized float somehow leaks into your system. That's not supposed to happen (IEEE-754 specifies which representation should be used if a number can be represented in more than one way), but it's something to keep in mind if you're operating on, say, data files provided by a hostile user.

    – Mark
    Jan 4 at 0:39


















-6














Binary compare works with too much precision for many actual applications. For example, in javascript, 0.2 / 10.0 != 0.1 * 0.2 If you have two variables that both end up with very, very slight rounding errors, they will be unequal despite representing the "same" number.






share|improve this answer


















  • 5





    Yes, but in that case both == and memcmp(…) (and, presumably, std::equals(…)) would agree, so that's not addressing the question. (Worth being aware of, though.)

    – gidds
    Jan 3 at 17:44






  • 1





    They are not the "same" number if their binary representation is different. If you want both numbers to be the same with two decimal precision then you round them. Then you define how you want to round them. You document that and have a reliable way of testing logic. What do you call the same number? Is this good enough for you 0.099998 == 0.99997? Is this good enough 0.099 == 0.098? Is this good enough 0.9 == 1.0?

    – FCin
    Jan 3 at 18:34











  • @FCin So, are you saying that 0.2*0.1 != 0.2/10.0? They aren't the same number because of rounding errors, not because the numbers they should represent are different. If your code only uses hardcoded numbers, then it's fine, but if any of the numbers are random or user-generated, then using == is a bad decision for floating point numbers and likely to introduce bugs.

    – David Rice
    Jan 3 at 18:42






  • 1





    As @gidds said, that's completely irrelevant to the question. The only time == differs from memcmp(...) occurs with NaN and +0 and -0. Also, there is a difference you're missing here: C floating point isn't mathematically perfect. If you put in 0.2 / 10.0 and 0.1 * 0.2 and expect them to evaluate to the same value, you need to read more about floating point.

    – user124
    Jan 3 at 20:16






  • 1





    @DavidRice is correct. A more complete answer referencing epsilon can be found here.

    – jacknad
    Jan 3 at 21:14










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%2f54020760%2fis-binary-equality-comparison-of-floats-correct%23new-answer', 'question_page');

);

Post as a guest















Required, but never shown

























3 Answers
3






active

oldest

votes








3 Answers
3






active

oldest

votes









active

oldest

votes






active

oldest

votes









49














The first thing I would do if I were you is to check your optimisation settings.



It's fine to use memcmp for an array of floating points but note that you could get different results to element-by-element ==. In particular, for IEEE754 floating point:



  1. +0.0 is defined to compare equal to -0.0.


  2. NaN is defined to compare not-equal to NaN.






share|improve this answer




















  • 3





    Also note that, technically, the C and C++ standards do not require the use of IEEE 754 to implement float and double. Most "reasonable" (modern) platforms will do so in practice, of course. But if you're uncertain that IEEE 754 is in use, then you have very few guarantees of how the == operator will behave on arbitrary bit patterns. A "weird" architecture could for example decide that ((float)0x00000000) == ((float)0x12345678), but memcmp will obviously consider those bytes different.

    – Kevin
    Jan 4 at 1:25











  • @Kevin: Indeed you're correct and I've narrowed the answer. I wonder if you fancy answering this question in more detail yourself; it seems to have attracted a lot of attention?

    – Bathsheba
    Jan 4 at 8:18











  • Thanks for the vote of confidence, but I don't really think I can add much to your answer as it now stands.

    – Kevin
    Jan 4 at 14:18















49














The first thing I would do if I were you is to check your optimisation settings.



It's fine to use memcmp for an array of floating points but note that you could get different results to element-by-element ==. In particular, for IEEE754 floating point:



  1. +0.0 is defined to compare equal to -0.0.


  2. NaN is defined to compare not-equal to NaN.






share|improve this answer




















  • 3





    Also note that, technically, the C and C++ standards do not require the use of IEEE 754 to implement float and double. Most "reasonable" (modern) platforms will do so in practice, of course. But if you're uncertain that IEEE 754 is in use, then you have very few guarantees of how the == operator will behave on arbitrary bit patterns. A "weird" architecture could for example decide that ((float)0x00000000) == ((float)0x12345678), but memcmp will obviously consider those bytes different.

    – Kevin
    Jan 4 at 1:25











  • @Kevin: Indeed you're correct and I've narrowed the answer. I wonder if you fancy answering this question in more detail yourself; it seems to have attracted a lot of attention?

    – Bathsheba
    Jan 4 at 8:18











  • Thanks for the vote of confidence, but I don't really think I can add much to your answer as it now stands.

    – Kevin
    Jan 4 at 14:18













49












49








49







The first thing I would do if I were you is to check your optimisation settings.



It's fine to use memcmp for an array of floating points but note that you could get different results to element-by-element ==. In particular, for IEEE754 floating point:



  1. +0.0 is defined to compare equal to -0.0.


  2. NaN is defined to compare not-equal to NaN.






share|improve this answer















The first thing I would do if I were you is to check your optimisation settings.



It's fine to use memcmp for an array of floating points but note that you could get different results to element-by-element ==. In particular, for IEEE754 floating point:



  1. +0.0 is defined to compare equal to -0.0.


  2. NaN is defined to compare not-equal to NaN.







share|improve this answer














share|improve this answer



share|improve this answer








edited Jan 4 at 8:12

























answered Jan 3 at 10:48









BathshebaBathsheba

176k27251373




176k27251373







  • 3





    Also note that, technically, the C and C++ standards do not require the use of IEEE 754 to implement float and double. Most "reasonable" (modern) platforms will do so in practice, of course. But if you're uncertain that IEEE 754 is in use, then you have very few guarantees of how the == operator will behave on arbitrary bit patterns. A "weird" architecture could for example decide that ((float)0x00000000) == ((float)0x12345678), but memcmp will obviously consider those bytes different.

    – Kevin
    Jan 4 at 1:25











  • @Kevin: Indeed you're correct and I've narrowed the answer. I wonder if you fancy answering this question in more detail yourself; it seems to have attracted a lot of attention?

    – Bathsheba
    Jan 4 at 8:18











  • Thanks for the vote of confidence, but I don't really think I can add much to your answer as it now stands.

    – Kevin
    Jan 4 at 14:18












  • 3





    Also note that, technically, the C and C++ standards do not require the use of IEEE 754 to implement float and double. Most "reasonable" (modern) platforms will do so in practice, of course. But if you're uncertain that IEEE 754 is in use, then you have very few guarantees of how the == operator will behave on arbitrary bit patterns. A "weird" architecture could for example decide that ((float)0x00000000) == ((float)0x12345678), but memcmp will obviously consider those bytes different.

    – Kevin
    Jan 4 at 1:25











  • @Kevin: Indeed you're correct and I've narrowed the answer. I wonder if you fancy answering this question in more detail yourself; it seems to have attracted a lot of attention?

    – Bathsheba
    Jan 4 at 8:18











  • Thanks for the vote of confidence, but I don't really think I can add much to your answer as it now stands.

    – Kevin
    Jan 4 at 14:18







3




3





Also note that, technically, the C and C++ standards do not require the use of IEEE 754 to implement float and double. Most "reasonable" (modern) platforms will do so in practice, of course. But if you're uncertain that IEEE 754 is in use, then you have very few guarantees of how the == operator will behave on arbitrary bit patterns. A "weird" architecture could for example decide that ((float)0x00000000) == ((float)0x12345678), but memcmp will obviously consider those bytes different.

– Kevin
Jan 4 at 1:25





Also note that, technically, the C and C++ standards do not require the use of IEEE 754 to implement float and double. Most "reasonable" (modern) platforms will do so in practice, of course. But if you're uncertain that IEEE 754 is in use, then you have very few guarantees of how the == operator will behave on arbitrary bit patterns. A "weird" architecture could for example decide that ((float)0x00000000) == ((float)0x12345678), but memcmp will obviously consider those bytes different.

– Kevin
Jan 4 at 1:25













@Kevin: Indeed you're correct and I've narrowed the answer. I wonder if you fancy answering this question in more detail yourself; it seems to have attracted a lot of attention?

– Bathsheba
Jan 4 at 8:18





@Kevin: Indeed you're correct and I've narrowed the answer. I wonder if you fancy answering this question in more detail yourself; it seems to have attracted a lot of attention?

– Bathsheba
Jan 4 at 8:18













Thanks for the vote of confidence, but I don't really think I can add much to your answer as it now stands.

– Kevin
Jan 4 at 14:18





Thanks for the vote of confidence, but I don't really think I can add much to your answer as it now stands.

– Kevin
Jan 4 at 14:18













14














The main issue is nan values, as these are never equal to themselves. There is also two representations of 0 (+0 and -0) that are equal but not binary equal.



So strictly speaking, you cannot use memcmp for them, as the answer would be mathematically incorrect.



If you know that you don't have nan or 0 values, then you can use memcmp.






share|improve this answer




















  • 5





    Zero has two representations in IEEE-754 binary floating-point, denoted as −0 and +0. They represent the same mathematical value and should be reported as equal, which == does but memcmp does not.

    – Eric Postpischil
    Jan 3 at 13:10






  • 1





    Yes indeed, that's why I said the main issue, of course, there is 0 as well.

    – Matthieu Brucher
    Jan 3 at 13:30






  • 1





    There's another way to get two numbers that compare numerically equal but not binary equal: if a denormalized float somehow leaks into your system. That's not supposed to happen (IEEE-754 specifies which representation should be used if a number can be represented in more than one way), but it's something to keep in mind if you're operating on, say, data files provided by a hostile user.

    – Mark
    Jan 4 at 0:39















14














The main issue is nan values, as these are never equal to themselves. There is also two representations of 0 (+0 and -0) that are equal but not binary equal.



So strictly speaking, you cannot use memcmp for them, as the answer would be mathematically incorrect.



If you know that you don't have nan or 0 values, then you can use memcmp.






share|improve this answer




















  • 5





    Zero has two representations in IEEE-754 binary floating-point, denoted as −0 and +0. They represent the same mathematical value and should be reported as equal, which == does but memcmp does not.

    – Eric Postpischil
    Jan 3 at 13:10






  • 1





    Yes indeed, that's why I said the main issue, of course, there is 0 as well.

    – Matthieu Brucher
    Jan 3 at 13:30






  • 1





    There's another way to get two numbers that compare numerically equal but not binary equal: if a denormalized float somehow leaks into your system. That's not supposed to happen (IEEE-754 specifies which representation should be used if a number can be represented in more than one way), but it's something to keep in mind if you're operating on, say, data files provided by a hostile user.

    – Mark
    Jan 4 at 0:39













14












14








14







The main issue is nan values, as these are never equal to themselves. There is also two representations of 0 (+0 and -0) that are equal but not binary equal.



So strictly speaking, you cannot use memcmp for them, as the answer would be mathematically incorrect.



If you know that you don't have nan or 0 values, then you can use memcmp.






share|improve this answer















The main issue is nan values, as these are never equal to themselves. There is also two representations of 0 (+0 and -0) that are equal but not binary equal.



So strictly speaking, you cannot use memcmp for them, as the answer would be mathematically incorrect.



If you know that you don't have nan or 0 values, then you can use memcmp.







share|improve this answer














share|improve this answer



share|improve this answer








edited Jan 3 at 13:50

























answered Jan 3 at 10:48









Matthieu BrucherMatthieu Brucher

13.7k32140




13.7k32140







  • 5





    Zero has two representations in IEEE-754 binary floating-point, denoted as −0 and +0. They represent the same mathematical value and should be reported as equal, which == does but memcmp does not.

    – Eric Postpischil
    Jan 3 at 13:10






  • 1





    Yes indeed, that's why I said the main issue, of course, there is 0 as well.

    – Matthieu Brucher
    Jan 3 at 13:30






  • 1





    There's another way to get two numbers that compare numerically equal but not binary equal: if a denormalized float somehow leaks into your system. That's not supposed to happen (IEEE-754 specifies which representation should be used if a number can be represented in more than one way), but it's something to keep in mind if you're operating on, say, data files provided by a hostile user.

    – Mark
    Jan 4 at 0:39












  • 5





    Zero has two representations in IEEE-754 binary floating-point, denoted as −0 and +0. They represent the same mathematical value and should be reported as equal, which == does but memcmp does not.

    – Eric Postpischil
    Jan 3 at 13:10






  • 1





    Yes indeed, that's why I said the main issue, of course, there is 0 as well.

    – Matthieu Brucher
    Jan 3 at 13:30






  • 1





    There's another way to get two numbers that compare numerically equal but not binary equal: if a denormalized float somehow leaks into your system. That's not supposed to happen (IEEE-754 specifies which representation should be used if a number can be represented in more than one way), but it's something to keep in mind if you're operating on, say, data files provided by a hostile user.

    – Mark
    Jan 4 at 0:39







5




5





Zero has two representations in IEEE-754 binary floating-point, denoted as −0 and +0. They represent the same mathematical value and should be reported as equal, which == does but memcmp does not.

– Eric Postpischil
Jan 3 at 13:10





Zero has two representations in IEEE-754 binary floating-point, denoted as −0 and +0. They represent the same mathematical value and should be reported as equal, which == does but memcmp does not.

– Eric Postpischil
Jan 3 at 13:10




1




1





Yes indeed, that's why I said the main issue, of course, there is 0 as well.

– Matthieu Brucher
Jan 3 at 13:30





Yes indeed, that's why I said the main issue, of course, there is 0 as well.

– Matthieu Brucher
Jan 3 at 13:30




1




1





There's another way to get two numbers that compare numerically equal but not binary equal: if a denormalized float somehow leaks into your system. That's not supposed to happen (IEEE-754 specifies which representation should be used if a number can be represented in more than one way), but it's something to keep in mind if you're operating on, say, data files provided by a hostile user.

– Mark
Jan 4 at 0:39





There's another way to get two numbers that compare numerically equal but not binary equal: if a denormalized float somehow leaks into your system. That's not supposed to happen (IEEE-754 specifies which representation should be used if a number can be represented in more than one way), but it's something to keep in mind if you're operating on, say, data files provided by a hostile user.

– Mark
Jan 4 at 0:39











-6














Binary compare works with too much precision for many actual applications. For example, in javascript, 0.2 / 10.0 != 0.1 * 0.2 If you have two variables that both end up with very, very slight rounding errors, they will be unequal despite representing the "same" number.






share|improve this answer


















  • 5





    Yes, but in that case both == and memcmp(…) (and, presumably, std::equals(…)) would agree, so that's not addressing the question. (Worth being aware of, though.)

    – gidds
    Jan 3 at 17:44






  • 1





    They are not the "same" number if their binary representation is different. If you want both numbers to be the same with two decimal precision then you round them. Then you define how you want to round them. You document that and have a reliable way of testing logic. What do you call the same number? Is this good enough for you 0.099998 == 0.99997? Is this good enough 0.099 == 0.098? Is this good enough 0.9 == 1.0?

    – FCin
    Jan 3 at 18:34











  • @FCin So, are you saying that 0.2*0.1 != 0.2/10.0? They aren't the same number because of rounding errors, not because the numbers they should represent are different. If your code only uses hardcoded numbers, then it's fine, but if any of the numbers are random or user-generated, then using == is a bad decision for floating point numbers and likely to introduce bugs.

    – David Rice
    Jan 3 at 18:42






  • 1





    As @gidds said, that's completely irrelevant to the question. The only time == differs from memcmp(...) occurs with NaN and +0 and -0. Also, there is a difference you're missing here: C floating point isn't mathematically perfect. If you put in 0.2 / 10.0 and 0.1 * 0.2 and expect them to evaluate to the same value, you need to read more about floating point.

    – user124
    Jan 3 at 20:16






  • 1





    @DavidRice is correct. A more complete answer referencing epsilon can be found here.

    – jacknad
    Jan 3 at 21:14















-6














Binary compare works with too much precision for many actual applications. For example, in javascript, 0.2 / 10.0 != 0.1 * 0.2 If you have two variables that both end up with very, very slight rounding errors, they will be unequal despite representing the "same" number.






share|improve this answer


















  • 5





    Yes, but in that case both == and memcmp(…) (and, presumably, std::equals(…)) would agree, so that's not addressing the question. (Worth being aware of, though.)

    – gidds
    Jan 3 at 17:44






  • 1





    They are not the "same" number if their binary representation is different. If you want both numbers to be the same with two decimal precision then you round them. Then you define how you want to round them. You document that and have a reliable way of testing logic. What do you call the same number? Is this good enough for you 0.099998 == 0.99997? Is this good enough 0.099 == 0.098? Is this good enough 0.9 == 1.0?

    – FCin
    Jan 3 at 18:34











  • @FCin So, are you saying that 0.2*0.1 != 0.2/10.0? They aren't the same number because of rounding errors, not because the numbers they should represent are different. If your code only uses hardcoded numbers, then it's fine, but if any of the numbers are random or user-generated, then using == is a bad decision for floating point numbers and likely to introduce bugs.

    – David Rice
    Jan 3 at 18:42






  • 1





    As @gidds said, that's completely irrelevant to the question. The only time == differs from memcmp(...) occurs with NaN and +0 and -0. Also, there is a difference you're missing here: C floating point isn't mathematically perfect. If you put in 0.2 / 10.0 and 0.1 * 0.2 and expect them to evaluate to the same value, you need to read more about floating point.

    – user124
    Jan 3 at 20:16






  • 1





    @DavidRice is correct. A more complete answer referencing epsilon can be found here.

    – jacknad
    Jan 3 at 21:14













-6












-6








-6







Binary compare works with too much precision for many actual applications. For example, in javascript, 0.2 / 10.0 != 0.1 * 0.2 If you have two variables that both end up with very, very slight rounding errors, they will be unequal despite representing the "same" number.






share|improve this answer













Binary compare works with too much precision for many actual applications. For example, in javascript, 0.2 / 10.0 != 0.1 * 0.2 If you have two variables that both end up with very, very slight rounding errors, they will be unequal despite representing the "same" number.







share|improve this answer












share|improve this answer



share|improve this answer










answered Jan 3 at 16:50









David RiceDavid Rice

1282




1282







  • 5





    Yes, but in that case both == and memcmp(…) (and, presumably, std::equals(…)) would agree, so that's not addressing the question. (Worth being aware of, though.)

    – gidds
    Jan 3 at 17:44






  • 1





    They are not the "same" number if their binary representation is different. If you want both numbers to be the same with two decimal precision then you round them. Then you define how you want to round them. You document that and have a reliable way of testing logic. What do you call the same number? Is this good enough for you 0.099998 == 0.99997? Is this good enough 0.099 == 0.098? Is this good enough 0.9 == 1.0?

    – FCin
    Jan 3 at 18:34











  • @FCin So, are you saying that 0.2*0.1 != 0.2/10.0? They aren't the same number because of rounding errors, not because the numbers they should represent are different. If your code only uses hardcoded numbers, then it's fine, but if any of the numbers are random or user-generated, then using == is a bad decision for floating point numbers and likely to introduce bugs.

    – David Rice
    Jan 3 at 18:42






  • 1





    As @gidds said, that's completely irrelevant to the question. The only time == differs from memcmp(...) occurs with NaN and +0 and -0. Also, there is a difference you're missing here: C floating point isn't mathematically perfect. If you put in 0.2 / 10.0 and 0.1 * 0.2 and expect them to evaluate to the same value, you need to read more about floating point.

    – user124
    Jan 3 at 20:16






  • 1





    @DavidRice is correct. A more complete answer referencing epsilon can be found here.

    – jacknad
    Jan 3 at 21:14












  • 5





    Yes, but in that case both == and memcmp(…) (and, presumably, std::equals(…)) would agree, so that's not addressing the question. (Worth being aware of, though.)

    – gidds
    Jan 3 at 17:44






  • 1





    They are not the "same" number if their binary representation is different. If you want both numbers to be the same with two decimal precision then you round them. Then you define how you want to round them. You document that and have a reliable way of testing logic. What do you call the same number? Is this good enough for you 0.099998 == 0.99997? Is this good enough 0.099 == 0.098? Is this good enough 0.9 == 1.0?

    – FCin
    Jan 3 at 18:34











  • @FCin So, are you saying that 0.2*0.1 != 0.2/10.0? They aren't the same number because of rounding errors, not because the numbers they should represent are different. If your code only uses hardcoded numbers, then it's fine, but if any of the numbers are random or user-generated, then using == is a bad decision for floating point numbers and likely to introduce bugs.

    – David Rice
    Jan 3 at 18:42






  • 1





    As @gidds said, that's completely irrelevant to the question. The only time == differs from memcmp(...) occurs with NaN and +0 and -0. Also, there is a difference you're missing here: C floating point isn't mathematically perfect. If you put in 0.2 / 10.0 and 0.1 * 0.2 and expect them to evaluate to the same value, you need to read more about floating point.

    – user124
    Jan 3 at 20:16






  • 1





    @DavidRice is correct. A more complete answer referencing epsilon can be found here.

    – jacknad
    Jan 3 at 21:14







5




5





Yes, but in that case both == and memcmp(…) (and, presumably, std::equals(…)) would agree, so that's not addressing the question. (Worth being aware of, though.)

– gidds
Jan 3 at 17:44





Yes, but in that case both == and memcmp(…) (and, presumably, std::equals(…)) would agree, so that's not addressing the question. (Worth being aware of, though.)

– gidds
Jan 3 at 17:44




1




1





They are not the "same" number if their binary representation is different. If you want both numbers to be the same with two decimal precision then you round them. Then you define how you want to round them. You document that and have a reliable way of testing logic. What do you call the same number? Is this good enough for you 0.099998 == 0.99997? Is this good enough 0.099 == 0.098? Is this good enough 0.9 == 1.0?

– FCin
Jan 3 at 18:34





They are not the "same" number if their binary representation is different. If you want both numbers to be the same with two decimal precision then you round them. Then you define how you want to round them. You document that and have a reliable way of testing logic. What do you call the same number? Is this good enough for you 0.099998 == 0.99997? Is this good enough 0.099 == 0.098? Is this good enough 0.9 == 1.0?

– FCin
Jan 3 at 18:34













@FCin So, are you saying that 0.2*0.1 != 0.2/10.0? They aren't the same number because of rounding errors, not because the numbers they should represent are different. If your code only uses hardcoded numbers, then it's fine, but if any of the numbers are random or user-generated, then using == is a bad decision for floating point numbers and likely to introduce bugs.

– David Rice
Jan 3 at 18:42





@FCin So, are you saying that 0.2*0.1 != 0.2/10.0? They aren't the same number because of rounding errors, not because the numbers they should represent are different. If your code only uses hardcoded numbers, then it's fine, but if any of the numbers are random or user-generated, then using == is a bad decision for floating point numbers and likely to introduce bugs.

– David Rice
Jan 3 at 18:42




1




1





As @gidds said, that's completely irrelevant to the question. The only time == differs from memcmp(...) occurs with NaN and +0 and -0. Also, there is a difference you're missing here: C floating point isn't mathematically perfect. If you put in 0.2 / 10.0 and 0.1 * 0.2 and expect them to evaluate to the same value, you need to read more about floating point.

– user124
Jan 3 at 20:16





As @gidds said, that's completely irrelevant to the question. The only time == differs from memcmp(...) occurs with NaN and +0 and -0. Also, there is a difference you're missing here: C floating point isn't mathematically perfect. If you put in 0.2 / 10.0 and 0.1 * 0.2 and expect them to evaluate to the same value, you need to read more about floating point.

– user124
Jan 3 at 20:16




1




1





@DavidRice is correct. A more complete answer referencing epsilon can be found here.

– jacknad
Jan 3 at 21:14





@DavidRice is correct. A more complete answer referencing epsilon can be found here.

– jacknad
Jan 3 at 21:14

















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.




draft saved


draft discarded














StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f54020760%2fis-binary-equality-comparison-of-floats-correct%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






Popular posts from this blog

How to check contact read email or not when send email to Individual?

Bahrain

Postfix configuration issue with fips on centos 7; mailgun relay