From: Goran on
On Mar 2, 8:30 pm, Andy Johnson <ajcpp...(a)gmail.com> wrote:
> Hi All
>
> I've searched for a definitive solution but couldn't find one. So I
> came here...
>
> Can I use a floating point number (either single or double precision)
> as the key for a map (and it work correctly)?
>
> I'm aware of the issues with floating point equality but as the map is
> doing equivalence (strict weak ordering) wondered whether it would
> just work or will I have to write my own compare functor.

As usual with floating-point comparison, it will work, but might not
give you what you need :-).

It's easy to see why: you obtain one key through a calculation. You
obtain another and it's close enough to the first that it should be
considered same as the first. But since it's not __exactly__ the same,
you'll e.g. end up with two key-value pairs in the map. The question
is simply: at what point two close values are one?

Goran.


--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

From: Louis Lavery on
Andy Johnson wrote:
> Hi All
>
> I've searched for a definitive solution but couldn't find one. So I
> came here...
>
> Can I use a floating point number (either single or double precision)
> as the key for a map (and it work correctly)?

So long as the comparison defines a strict weak ordering then it'll
work correctly, no matter the type.

So, does floating point < define a strict weak ordering?

If you avoid NANs (and as -0.0 and +0.0 behave as equals when compared)
then yes.

Louis.

--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

From: Pete Becker on
Bart van Ingen Schenau wrote:
>
> Just be aware that finding a particular key might not work as you
> expect, due to differences in precision/rount-off error between the
> stored key and the value you are trying to match it with.
>

In other words, finding a particular key might not work if you instead
look for a different key.

--
Pete
Roundhouse Consulting, Ltd. (www.versatilecoding.com) Author of
"The Standard C++ Library Extensions: a Tutorial and Reference"
(www.petebecker.com/tr1book)

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

From: Pete Becker on
Ulrich Eckhardt wrote:
> Andy Johnson wrote:
>> Can I use a floating point number (either single or double precision)
>> as the key for a map (and it work correctly)?
>
> Define "correctly". You will have numbers that are almost indistinguishable
> from each other but compare unequal.
>

Or, to put it the other way around, you will have numbers that are not
equal and compare unequal.

As always, the issue is not whether equality means equality, but whether
the programmer knows enough about the source of the numbers to
understand whether they should be equal.

It's really not that much different from this:

int a = 1/3;
int b = a * 3;
assert(b == 1);

Gasp! The assert triggers! == isn't doing what it's supposed to do.

The difference is that most programmers have learned the rules for
integer arithmetic. Far fewer have learned the rules for floating-point
arithmetic, and instead resort to incantations.

--
Pete
Roundhouse Consulting, Ltd. (www.versatilecoding.com) Author of
"The Standard C++ Library Extensions: a Tutorial and Reference"
(www.petebecker.com/tr1book)

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

From: Francis Glassborow on
Goran wrote:
> On Mar 2, 8:30 pm, Andy Johnson <ajcpp...(a)gmail.com> wrote:
>> Hi All
>>
>> I've searched for a definitive solution but couldn't find one. So I
>> came here...
>>
>> Can I use a floating point number (either single or double precision)
>> as the key for a map (and it work correctly)?
>>
>> I'm aware of the issues with floating point equality but as the map is
>> doing equivalence (strict weak ordering) wondered whether it would
>> just work or will I have to write my own compare functor.
>
> As usual with floating-point comparison, it will work, but might not
> give you what you need :-).
>
> It's easy to see why: you obtain one key through a calculation. You
> obtain another and it's close enough to the first that it should be
> considered same as the first. But since it's not __exactly__ the same,
> you'll e.g. end up with two key-value pairs in the map. The question
> is simply: at what point two close values are one?
>
> Goran.
>
And the trouble with that is that almost equality is not a transitive
operation. Suppose that you define almost equality to be a difference of
no more than epsilon and you have three values x-epsilon, x and
x+epsilon. The first and last are almost equal to the middle one but the
two extreme values differ by 2*epsilon.

--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]