可靠地使用双精度作为std :: map键

时间:2014-07-24 14:51:55

标签: c++ map floating-point key double

我的一位同事最近提出了一个有趣的技巧,可靠地使用浮点数作为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这样的东西,以便可靠地检索特定价格水平的订单。

是否存在这样的逻辑会失败的情况?我尝试为自己制定一个证明为什么这样可行的证据,但我认为我没有足够的浮点运算经验来推理它出来了。

1 个答案:

答案 0 :(得分:2)

首先,您不应该除以ticksize,您应该乘以ticksize的倒数,考虑到您描述的应用,它可能完全可以表示为double。在您的示例中,此反转为20.0

其次,您可以使转换稍微简单,因此我认为更具可读性:

price乘以ticksize的倒数后,将其从double变为最接近的整数,作为long long(函数llround)或{{1 (函数double)。只要您使用兼容的哈希和相等函数(哈希函数应该为+0返回相同的哈希值),就不应该使用nearbyint作为double的键,这是没有内在的原因。 -0。如果相等是std::map,并且如果使用==作为相等,则可能不应该使用NaN作为键。

在代码中:

==