我的一位同事最近提出了一个有趣的技巧,可靠地使用浮点数作为C ++中std::map
之类的键。
假设您希望对某些浮点值(例如price
)进行处理,并且您知道这些值只能表示离散值,尽管表示实数(例如,以某个{{1}的间隔}),然后以下代码段可靠地将输入ticksize
转换为price
价格键:
long long
例如,如果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));
}
和price = 98.05
,那么我们最终会得到以下结果:
ticksize = 0.05
然后 price / ticksize = 1960.9999999999998
ticksize / 2 = 0.025
priceKey = (long long) 1960.9999999999998 + 0.025 = 1961
可以继续用于像priceKey
这样的东西,以便可靠地检索特定价格水平的订单。
是否存在这样的逻辑会失败的情况?我尝试为自己制定一个证明为什么这样可行的证据,但我认为我没有足够的浮点运算经验来推理它出来了。
答案 0 :(得分:2)
首先,您不应该除以ticksize
,您应该乘以ticksize
的倒数,考虑到您描述的应用,它可能完全可以表示为double
。在您的示例中,此反转为20.0
。
其次,您可以使转换稍微简单,因此我认为更具可读性:
将price
乘以ticksize
的倒数后,将其从double变为最接近的整数,作为long long
(函数llround
)或{{1 (函数double
)。只要您使用兼容的哈希和相等函数(哈希函数应该为+0返回相同的哈希值),就不应该使用nearbyint
作为double
的键,这是没有内在的原因。 -0。如果相等是std::map
,并且如果使用==
作为相等,则可能不应该使用NaN作为键。
在代码中:
==