5

我的项目中有一些代码比较了两个双精度值,看它们的差值是否超过 0,例如:

if (totValue != 1.0)

Resharper 对此提出了抱怨,建议我应该使用“EPSILON”并在代码中添加这样一个常量(当被邀请时)。但是,它不会创建常量本身或建议它应该是什么值。这是一个很好的解决方案:

const double EPSILON = double.Epsilon; // see http://msdn.microsoft.com/en-us/library/system.double.epsilon.aspx
. . .
if (Math.Abs(totValue - 1.0) > EPSILON)
    compValue = Convert.ToString(totValue*Convert.ToDouble(compValue));

?

更新

我把它改成这样:

const double EPSILON = 0.001;

...认为这可能既大又小,足以适用于典型的双 vals(不是科学的东西,只是“我有 2.5 个”等)

4

2 回答 2

3

不,这对您的 epsilon 来说不是一个明智的值。您拥有的代码与直接相等检查没有什么不同。

double.Epsilon是任何两个双打之间可能存在的最小差异。任何两个双打都没有办法比分开更靠近彼此double.Epsilon,所以这个检查为真的唯一方法是让它们完全相等。

至于您应该实际使用什么 epsilon 值,这完全取决于,这就是为什么不会为您自动生成一个。这完全取决于您对数据执行的操作类型(这会影响与“真实值”的可能偏差)以及应用程序中实际关心的精度(当然,如果您关心的精度大于您的误差范围,您有问题)。您的 epsilon 需要某个精度值大于(或等于)您需要的精度,同时小于对任一数值执行的所有操作的可能误差范围。

于 2014-06-18T18:23:46.370 回答
1

是的。但更好的是不使用浮点数。使用decimalinstad。

但是,如果由于某种原因,您必须坚持double从不直接比较,这意味着,永远不要依赖例如a-b == 0with (a并且b是一些double本应相等的值)。

浮点运算速度很快,但并不精确,考虑到这一点,R# 是正确的。

于 2014-06-18T18:21:30.747 回答