One of my coworkers recently brought up an interesting trick to reliably use floating point numbers as keys in something like a std::map
in C++.
Assuming you want to case on some floating point value (like price
), and you know that these values can only take on discrete values despite representing real numbers (say, at intervals of a certain ticksize
), then the following code snippet reliably converts an input price
to a long long
price key:
double price, ticksize; // Initialized elsewhere
long long priceKey = 0;
if ((price / ticksize) < (ticksize / 2)) {
priceKey = (long long) (price / ticksize);
} else {
priceKey = (long long) ((price / ticksize) + (ticksize / 2));
}
For example, if price = 98.05
and ticksize = 0.05
, then we end up with the following result:
price / ticksize = 1960.9999999999998
ticksize / 2 = 0.025
priceKey = (long long) 1960.9999999999998 + 0.025 = 1961
priceKey
could then go on to be used in something like a std::map<long long, order_t>
to reliably retrieve orders at a particular price level.
Is there any case where such logic would fail? I tried working out a proof for myself of why this could work, but I don't think I have enough experience with floating point arithmetic to reason it out.