Is binary equality comparison of floats correct?












22














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
    18 hours ago






  • 1




    This answer to a related question is relevant to yours
    – Basile Starynkevitch
    18 hours ago






  • 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
    17 hours ago






  • 2




    Similar: stackoverflow.com/q/8044862/560648
    – Lightness Races in Orbit
    17 hours ago










  • @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
    16 hours ago
















22














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
    18 hours ago






  • 1




    This answer to a related question is relevant to yours
    – Basile Starynkevitch
    18 hours ago






  • 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
    17 hours ago






  • 2




    Similar: stackoverflow.com/q/8044862/560648
    – Lightness Races in Orbit
    17 hours ago










  • @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
    16 hours ago














22












22








22







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 18 hours ago









Zoltan Tirinda

439521




439521








  • 1




    Related: stackoverflow.com/questions/25808445/…
    – DeiDei
    18 hours ago






  • 1




    This answer to a related question is relevant to yours
    – Basile Starynkevitch
    18 hours ago






  • 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
    17 hours ago






  • 2




    Similar: stackoverflow.com/q/8044862/560648
    – Lightness Races in Orbit
    17 hours ago










  • @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
    16 hours ago














  • 1




    Related: stackoverflow.com/questions/25808445/…
    – DeiDei
    18 hours ago






  • 1




    This answer to a related question is relevant to yours
    – Basile Starynkevitch
    18 hours ago






  • 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
    17 hours ago






  • 2




    Similar: stackoverflow.com/q/8044862/560648
    – Lightness Races in Orbit
    17 hours ago










  • @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
    16 hours ago








1




1




Related: stackoverflow.com/questions/25808445/…
– DeiDei
18 hours ago




Related: stackoverflow.com/questions/25808445/…
– DeiDei
18 hours ago




1




1




This answer to a related question is relevant to yours
– Basile Starynkevitch
18 hours ago




This answer to a related question is relevant to yours
– Basile Starynkevitch
18 hours ago




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
17 hours ago




@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
17 hours ago




2




2




Similar: stackoverflow.com/q/8044862/560648
– Lightness Races in Orbit
17 hours ago




Similar: stackoverflow.com/q/8044862/560648
– Lightness Races in Orbit
17 hours ago












@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
16 hours ago




@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
16 hours ago












3 Answers
3






active

oldest

votes


















45














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 ==:




  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

















  • 1




    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
    3 hours ago



















13














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
    15 hours ago






  • 1




    Yes indeed, that's why I said the main issue, of course, there is 0 as well.
    – Matthieu Brucher
    15 hours ago










  • 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
    4 hours ago



















-5














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
    11 hours ago






  • 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
    10 hours ago










  • @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
    10 hours ago






  • 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
    8 hours ago






  • 1




    @DavidRice is correct. A more complete answer referencing epsilon can be found here.
    – jacknad
    7 hours ago











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









45














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 ==:




  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

















  • 1




    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
    3 hours ago
















45














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 ==:




  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

















  • 1




    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
    3 hours ago














45












45








45






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 ==:




  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 ==:




  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










answered 18 hours ago









Bathsheba

175k27249371




175k27249371








  • 1




    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
    3 hours ago














  • 1




    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
    3 hours ago








1




1




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
3 hours ago




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
3 hours ago













13














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
    15 hours ago






  • 1




    Yes indeed, that's why I said the main issue, of course, there is 0 as well.
    – Matthieu Brucher
    15 hours ago










  • 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
    4 hours ago
















13














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
    15 hours ago






  • 1




    Yes indeed, that's why I said the main issue, of course, there is 0 as well.
    – Matthieu Brucher
    15 hours ago










  • 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
    4 hours ago














13












13








13






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 15 hours ago

























answered 18 hours ago









Matthieu Brucher

12.4k22140




12.4k22140








  • 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
    15 hours ago






  • 1




    Yes indeed, that's why I said the main issue, of course, there is 0 as well.
    – Matthieu Brucher
    15 hours ago










  • 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
    4 hours ago














  • 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
    15 hours ago






  • 1




    Yes indeed, that's why I said the main issue, of course, there is 0 as well.
    – Matthieu Brucher
    15 hours ago










  • 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
    4 hours ago








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
15 hours ago




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
15 hours ago




1




1




Yes indeed, that's why I said the main issue, of course, there is 0 as well.
– Matthieu Brucher
15 hours ago




Yes indeed, that's why I said the main issue, of course, there is 0 as well.
– Matthieu Brucher
15 hours ago












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
4 hours ago




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
4 hours ago











-5














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
    11 hours ago






  • 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
    10 hours ago










  • @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
    10 hours ago






  • 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
    8 hours ago






  • 1




    @DavidRice is correct. A more complete answer referencing epsilon can be found here.
    – jacknad
    7 hours ago
















-5














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
    11 hours ago






  • 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
    10 hours ago










  • @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
    10 hours ago






  • 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
    8 hours ago






  • 1




    @DavidRice is correct. A more complete answer referencing epsilon can be found here.
    – jacknad
    7 hours ago














-5












-5








-5






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 12 hours ago









David Rice

1302




1302








  • 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
    11 hours ago






  • 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
    10 hours ago










  • @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
    10 hours ago






  • 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
    8 hours ago






  • 1




    @DavidRice is correct. A more complete answer referencing epsilon can be found here.
    – jacknad
    7 hours ago














  • 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
    11 hours ago






  • 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
    10 hours ago










  • @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
    10 hours ago






  • 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
    8 hours ago






  • 1




    @DavidRice is correct. A more complete answer referencing epsilon can be found here.
    – jacknad
    7 hours ago








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
11 hours ago




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
11 hours ago




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
10 hours ago




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
10 hours ago












@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
10 hours ago




@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
10 hours ago




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
8 hours ago




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
8 hours ago




1




1




@DavidRice is correct. A more complete answer referencing epsilon can be found here.
– jacknad
7 hours ago




@DavidRice is correct. A more complete answer referencing epsilon can be found here.
– jacknad
7 hours ago


















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%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

An IMO inspired problem

Management

Has there ever been an instance of an active nuclear power plant within or near a war zone?