Ways to use double as key in std set / map

The problem of using doubles as keys in maps / sets is floating point precision.

Some people suggested adding epsilon to your comparison function, but that means that your keys will no longer fulfill the necessary strict weak ordering criteria. This means that you will get a different set / map depending on the insertion order of your elements.

In case you want to combine / combine / combine data based on double values ​​and are ready to allow a certain level of rounding / epsilon (obviously you will have to), the following solution is a good idea

Convert all doubles (where we assign as keys) to integers, multiplying them by an accuracy coefficient (e.g. 1e8) and rounding to the nearest integer (int)i+0.5 (if i> 0), then create a set / map, which is the keys to these integers. When retrieving the final key values, divide the int by a precision factor to return a double value (albeit rounded).

+7
c ++ dictionary set floating-point key
source share
2 answers

"Convert all doubles (where we intended as keys) to integers, multiplying them by an accuracy factor (for example, 1e8) and rounding to the nearest integer (int)i+0.5 (if i> 0), then create a set / map that the keys to these integers: When extracting the final key values, divide the int by the precision factor to get a double value back (albeit rounded).

I would recommend using keys with an integer type (for example, long long ) for the map in the first place and trimming them for double representation using fixed precision for division.

But it depends if you can apply correct math points for your actual use case. If you need to cover a wide range of values ​​(for example, + -1e-7 - + -1e7), this approach will not work.

+3
source share

Convert all doubles (where we intended as keys) to integers, multiplying them by an accuracy factor (for example, 1e8) and rounding to the nearest integer (int) i + 0.5 (if i> 0), then create a set / map which is the keys of these integers. When retrieving the final key values, divide the int by the precision factor to get a double value back (although rounded).

Instead of dividing by the accuracy factor to get the doubling back, just save the double along with the associated value in the structure and put this structure in the dictionary as the “value” for this integer key. Thus, the double value of the original is still around and can be used for calculations. Just not for finding keys.

If, however, you can live with slightly rounded values ​​(due to the fact that you just divide the integer by epsilon), your proposed approach is already pretty good.

As another answer says, it is very dependent on a range of values. If some of them are extremely large and others are very small, then your approach to getting whole keys will not work. If they are only a few digits, then it could be.

+1
source share