我即将创建一个字典,其中每个值都有一个数字键,通过实验计算获得。
我知道double
任何其他浮点类型都不太适合用作键,因为很难比较两个浮点数的唯一性或相等性。
有谁知道在Decimal
这方面是否是一个好的候选人?另一种方法是将双精度转换为具有给定精度的字符串,但这对我来说听起来像是一种不雅的解决方法。
我即将创建一个字典,其中每个值都有一个数字键,通过实验计算获得。
我知道double
任何其他浮点类型都不太适合用作键,因为很难比较两个浮点数的唯一性或相等性。
有谁知道在Decimal
这方面是否是一个好的候选人?另一种方法是将双精度转换为具有给定精度的字符串,但这对我来说听起来像是一种不雅的解决方法。
在字典中使用float
或作为键没有太大区别。decimal
两者都用指数表示数字 - 所以两者都遭受相同的比较问题,只是规模不同。
如果您需要按位相等,则 Dictionary 都可以,如果您需要“大约相同的值”的键,则需要将其设为自定义键,该键将以某种已知的方式舍入值以将相似的结果放在同一个存储桶中。 ..
如果你正在使用decimal
或者double
因为int
不够大,可以考虑long
改用。
另外,我认为比较decimal
s 或double
s 应该没问题,只要没有小数/小数部分,并且只包含整数(-1,0,1,2,3 等)
(虽然我不建议在比较重要的地方使用decimal
/double
以避免将来出现任何意外错误)
如果您只处理 6 位精度,那么转换为int
应该没问题。
我知道这是一个老问题,但我相信我的回答可以帮助某人。
我真的需要浮动键。
当然,我遇到了精度问题,而且我的字典比它需要的大得多(我希望它例如1.0
并被0.999998
视为相同)。使用固定数量的十进制数字并不是一个很好的解决方案(例如,按照 OP 的建议将其转换为字符串),因为它使用绝对误差进行比较,而相对误差更为普遍。
我最终写了以下方法:
float Quantize(float x)
{
const float relMaxQuantError = 0.001f;
float ret = Mathf.Log10(Mathf.Abs(x));
float quantum = Mathf.Log10(1+relMaxQuantError);
ret = Mathf.Floor(ret/quantum) * quantum;
ret = Mathf.Sign(x) * (Mathf.Pow(10, ret));
return ret;
}
在将浮点数存储在字典中之前,我使用此方法对浮点数进行量化。允许的最大相对误差可以由 const 控制(目前为 0.1 %)。
PS:Mathf
是Unity的类。它可以很容易地调整以使用标准Math
.