Is binary equality comparison of floats correct?
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
|
show 1 more comment
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
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
|
show 1 more comment
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
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
c++ floating-point std
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
|
show 1 more comment
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
|
show 1 more comment
3 Answers
3
active
oldest
votes
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 ==
:
+0.0 is defined to compare equal to -0.0.
NaN is defined to compare not-equal to NaN.
1
Also note that, technically, the C and C++ standards do not require the use of IEEE 754 to implementfloat
anddouble
. 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)
, butmemcmp
will obviously consider those bytes different.
– Kevin
3 hours ago
add a comment |
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
.
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 butmemcmp
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
add a comment |
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.
5
Yes, but in that case both==
andmemcmp(…)
(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 frommemcmp(...)
occurs withNaN
and +0 and -0. Also, there is a difference you're missing here: C floating point isn't mathematically perfect. If you put in0.2 / 10.0
and0.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
|
show 5 more comments
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
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
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 ==
:
+0.0 is defined to compare equal to -0.0.
NaN is defined to compare not-equal to NaN.
1
Also note that, technically, the C and C++ standards do not require the use of IEEE 754 to implementfloat
anddouble
. 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)
, butmemcmp
will obviously consider those bytes different.
– Kevin
3 hours ago
add a comment |
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 ==
:
+0.0 is defined to compare equal to -0.0.
NaN is defined to compare not-equal to NaN.
1
Also note that, technically, the C and C++ standards do not require the use of IEEE 754 to implementfloat
anddouble
. 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)
, butmemcmp
will obviously consider those bytes different.
– Kevin
3 hours ago
add a comment |
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 ==
:
+0.0 is defined to compare equal to -0.0.
NaN is defined to compare not-equal to NaN.
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 ==
:
+0.0 is defined to compare equal to -0.0.
NaN is defined to compare not-equal to NaN.
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 implementfloat
anddouble
. 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)
, butmemcmp
will obviously consider those bytes different.
– Kevin
3 hours ago
add a comment |
1
Also note that, technically, the C and C++ standards do not require the use of IEEE 754 to implementfloat
anddouble
. 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)
, butmemcmp
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
add a comment |
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
.
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 butmemcmp
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
add a comment |
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
.
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 butmemcmp
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
add a comment |
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
.
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
.
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 butmemcmp
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
add a comment |
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 butmemcmp
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
add a comment |
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.
5
Yes, but in that case both==
andmemcmp(…)
(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 frommemcmp(...)
occurs withNaN
and +0 and -0. Also, there is a difference you're missing here: C floating point isn't mathematically perfect. If you put in0.2 / 10.0
and0.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
|
show 5 more comments
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.
5
Yes, but in that case both==
andmemcmp(…)
(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 frommemcmp(...)
occurs withNaN
and +0 and -0. Also, there is a difference you're missing here: C floating point isn't mathematically perfect. If you put in0.2 / 10.0
and0.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
|
show 5 more comments
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.
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.
answered 12 hours ago
David Rice
1302
1302
5
Yes, but in that case both==
andmemcmp(…)
(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 frommemcmp(...)
occurs withNaN
and +0 and -0. Also, there is a difference you're missing here: C floating point isn't mathematically perfect. If you put in0.2 / 10.0
and0.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
|
show 5 more comments
5
Yes, but in that case both==
andmemcmp(…)
(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 frommemcmp(...)
occurs withNaN
and +0 and -0. Also, there is a difference you're missing here: C floating point isn't mathematically perfect. If you put in0.2 / 10.0
and0.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
|
show 5 more comments
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.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
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
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