在std set / map中使用double作为键的方法

时间:2015-06-29 16:56:55

标签: c++ dictionary floating-point set key

在地图/集合中使用双精度键的问题是浮点精度。

有些人建议在比较功能中添加epsilon,但这意味着您的密钥将不再满足必要的严格弱排序标准。这意味着您将获得不同的集/映射,具体取决于插入元素的顺序。

如果你想基于双值聚合/组合/合并数据,并且愿意允许一定程度的舍入/ epsilon(显然,你将不得不),以下解决方案是一个好主意?

将所有双精度数(我们打算作为键)转换为整数,方法是将它们乘以精度因子(例如1e8)并舍入到最接近的整数(int)i+0.5(如果i> 0),然后创建一个/映射关键这些整数。在提取键的最终值时,将int除以精度因子以获得双值(尽管是舍入的)。

2 个答案:

答案 0 :(得分:3)

  

“将所有双精度数(我们用作键的位置)转换为整数,方法是将它们乘以精度因子(例如1e8)并舍入到最接近的整数(int)i+0.5(如果i> 0),然后创建一个关闭这些整数的集合/映射。在提取键的最终值时,将整数除以精度因子以获得双值(尽管是舍入的)。“

我建议首先使用整数类型的键(例如long long)作为地图,并使用固定的精度进行修剪以进行双重表示。

但这取决于您是否可以将fix point math用于实际用例。如果您需要涵盖各种值精度(例如+ -1e-7 - + -1e7),这种方法将无效。

答案 1 :(得分:1)

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

Instead of dividing by the precision factor to get the doubles back, simply store the double together with the associated value in a struct, and put that struct in the dictionary as the "value" for that integer key. That way, the original double value is still around and can be used for calculations. Just not for the key search.

If, however, you can live with slightly rounded values (due to the fact you simply divide an integer by an epsilon), your suggested approach is already good enough.

As the other answer says, it very much depends on the range of the values. If some are extremely huge and others are extremely small, then your approach to get integer keys won't work. If they are only a few digits apart, then it might.

相关问题