c++algorithmdictionarydata-structures

map with double keys C++


I have different stocks with their prices and I want to store them in the, for example std::map or std::unordered_map:

struct Stock
{
    ...
};

using stock_price_t = double;

std::map<stock_price_t, Stock> ordered_stocks;
std::unordered_map<stock_price_t, Stock> unordered_stocks;

Is it good idea use double keys in the dictionaries or better solutions is present?


Solution

  • A std::map has no issue with using doubles as key. It uses < to compare keys and two keys are equivalent when !(a < b) && !(b < a). That's fine. The issues do arise when you expect floating point numbers to be exact when in fact they are not.

    For example:

    std::map<double,int> m{{0.3,0},{1.0,2},{2.0,2},{3.0,3}};
    for (const auto& e : m) std::cout << e.first << " " << e.second << "\n";
    

    Output is:

    0.3 0
    1 2
    2 2
    3 3
    

    But now consider this:

    auto it = m.find(0.1 + 0.2);
    if (it == m.end()) std::cout << "not found\n";
    

    Searching 0.1 + 0.2 will not find the key 0.3, because doubles are not exact and the output is

    not found
    

    TL;DR: Do not use floating point numbers for prices or currencies. When you need prices with cents then use int cents:

    std::map<int, Stock> ordered_stocks;
    for (const auto& e : ordered_stocks) {
          std::cout << "dollars: " << e.first / 100 << "\n";
          std::cout << "stock: " << e.second << "\n";
    }