could the type of std::map's key be double or float?

107 Views Asked by At

I've writed a test case:

//environment: compiler=msvc140-x64 system=win10
#include <map>
#include <iostream>
int main(int argc, char* argv[])
{

    std::map<double, std::string> mapd2str;

    double dval1 = 1;
    mapd2str[dval1] = std::to_string(dval1);

    double dval2 = 1 + 1e-6;
    mapd2str[dval2] = std::to_string(dval2);

    for (auto& p : mapd2str)
    {
        std::cout << "first=" << p.first << ", second=" << p.second << std::endl;
    }

    return 0;
}

the output is as follow:

first=1, second=1.000000
first=1.00001, second=1.000010

after I changed the dval2 to 1 + 10e-20, the output is as follow:

first=1, second=1.000000

so, if I use the double or float as the key of std::map, is there any risk?

1

There are 1 best solutions below

4
463035818_is_not_an_ai On BEST ANSWER

It depends on what you refer to as "risk". The std::map is totally fine with float or double as keys.

A risk might be that keys you expect to be identical are not and that keys you expect to be different are in fact identical. 1 + 10e-20 is the same double as 1.0 because double has finite precision. There are other cases where intuition fails. See Is floating point math broken? for more details. Though, I repeat, the map has no issue with floating numbers as keys. If you insert a value for key 0.123 and later search for the value with key 0.123 you will find the right value. There is no risk in that.

If you do write a custom comparator, make sure it implements a strict weak ordering. The usual epsilon comparison of floating point numbers cannot do that! Also inf and nan require to take care when implementing the comparator.