我应该在字典中使用Decimal类型作为键吗

本文关键字:类型 Decimal 字典 我应该 | 更新日期: 2023-09-27 17:57:51

我将创建一个字典,其中每个值都有一个数字键,通过实验计算获得。

我知道double和任何其他浮点类型都不太适合用作键,因为很难比较两个浮点数的唯一性或相等性。

有人知道Decimal在这方面是否是一个好的候选人吗?另一种选择是以给定的精度将double转换为字符串,但在我看来这是一种不雅的变通方法。

我应该在字典中使用Decimal类型作为键吗

在字典中使用floatdecimal作为关键字没有太大区别。两者都用指数表示数字,所以两者在不同的尺度上都会遇到相同的比较问题。

如果你需要逐位相等,Dictionary可以使用这两种方法,如果你需要为"大约相同的值"设置关键字,你需要使其成为自定义关键字,以某种已知的方式对值进行四舍五入,将类似的结果放在同一个桶中。。。

如果因为int不够大而使用decimaldouble,请考虑使用long

此外,我认为比较decimal s或double s应该很好,只要没有小数部分,并且只包含整数(-1,0,1,2,3等)

(尽管我不建议在比较重要的情况下使用decimal/double,以避免任何未来的意外错误)

如果您只处理6位数的精度,那么转换为int应该没问题。

我知道这是一个老问题,但我相信我的答案可以帮助别人。

我真的需要浮动键。

当然,我遇到了精度问题,我的字典比它需要的大得多(我希望它像1.00.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

相关文章: