我应该在字典中使用Decimal类型作为键吗
本文关键字:类型 Decimal 字典 我应该 | 更新日期: 2023-09-27 17:57:51
我将创建一个字典,其中每个值都有一个数字键,通过实验计算获得。
我知道double
和任何其他浮点类型都不太适合用作键,因为很难比较两个浮点数的唯一性或相等性。
有人知道Decimal
在这方面是否是一个好的候选人吗?另一种选择是以给定的精度将double转换为字符串,但在我看来这是一种不雅的变通方法。
在字典中使用float
或decimal
作为关键字没有太大区别。两者都用指数表示数字,所以两者在不同的尺度上都会遇到相同的比较问题。
如果你需要逐位相等,Dictionary可以使用这两种方法,如果你需要为"大约相同的值"设置关键字,你需要使其成为自定义关键字,以某种已知的方式对值进行四舍五入,将类似的结果放在同一个桶中。。。
如果因为int
不够大而使用decimal
或double
,请考虑使用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;
}
在将浮点值存储到字典中之前,我使用此方法对其进行量化。允许的最大相对误差可以由常量控制(目前为0.1%)。
附言:Mathf
是Unity的班级。它可以很容易地调整为使用标准Math
。