【问题标题】:What is a reasonable Epsilon/Tolerance value for this image scaling code?此图像缩放代码的合理 Epsilon/Tolerance 值是多少?
【发布时间】:2016-05-23 20:59:18
【问题描述】:

Resharper 想要我更改这个现有代码:

if (pic.Height == oldH)
{
    pic.Height *= fX;
}

...到这个:

if (Math.Abs(pic.Height - oldH) < TOLERANCE)
{
    pic.Height *= fX;
}

...因为“浮点数与相等运算符的比较。舍入值时可能会丢失精度

“guttersnipe”(将鼠标悬停在代码左侧 Resharper 的灯泡图标上时弹出的工具提示)是“修复浮点数比较。比较与 Epsilon 的差异” p>

代码已经运行了几个月没有问题;我很高兴使用重新锐化的代码版本让它变得更好,但是:Epsilon(“TOLERANCE”)的值应该是多少?

这是完整的代码:

internal static void ScalePicture(Picture pic, double width, double height)
{
    var fX = width / pic.Width;
    var fY = height / pic.Height;
    var oldH = pic.Height;
    if (fX < fY)
    {
        pic.Width *= fX;
        if (pic.Height == oldH)
        {
            pic.Height *= fX;
        }
        pic.Top += (height - pic.Height) / 2;
    }
    else
    {
        pic.Width *= fY;
        if (pic.Height == oldH)
        {
            pic.Height *= fY;
        }
        pic.Left += (width - pic.Width) / 2;
    }
}

这样的事情是否合理:

const double TOLERANCE = 0.001;

?

注意:始终如一,R# 还希望将第二个“if (pic.Height == oldH)”与 TOLERANCE 进行比较。

【问题讨论】:

  • 听起来很合理;这个人类/空间将与之相伴,至少暂时如此。
  • 我遗漏了一些明显的东西,但是 oldH 如何在分配 pic.Height 的位置和测试它与 pic.Height 的相等性之间变化?也就是说,这些相等性测试不总是true 吗?
  • 好点;我从其他地方得到了这个代码;也许答案是平等测试更加挑剔;例如,赋值可能会分配 99.9999% 的值,或 100.0001% 的值,并且可以通过相等测试检测到微小的差异。
  • 我在回答中链接到的页面实际上建议您不要使用 Double.Epsilon:因为 Epsilon 定义了范围接近零的正值的最小表达式,因此两个相似值之间的差异幅度值必须大于 Epsilon。通常,它比 Epsilon 大很多倍。因此,我们建议您在比较 Double 值是否相等时不要使用 Epsilon。

标签: c# image resharper precision image-scaling


【解决方案1】:

在网上做了一些研究后,我使用这段代码比较双打。

public static bool EqualInPercentRange(this double Value1, double Value2, long Units = 2) {
  long longValue1 = BitConverter.DoubleToInt64Bits(Value1);
  long longValue2 = BitConverter.DoubleToInt64Bits(Value2);
  //
  // If the signs are different, return false except for +0 and -0.
  //
  if ((longValue1 >> 63) != (longValue2 >> 63)) {
    //
    // ReSharper disable once CompareOfFloatsByEqualityOperator
    //
    return Value1 == Value2;
  }

  long diff = Math.Abs(longValue1 - longValue2);

  return diff <= Units;
}

MSDN 原文出处:https://msdn.microsoft.com/en-us/library/ya2zha7s%28v=vs.110%29.aspx

【讨论】:

    【解决方案2】:

    如您所知,浮点数可以保存一个真正的连续值,在大多数情况下比较连续值时,如果它们之间的距离小于一个小阈值(epsilon),则这些值被认为是相等的,显然这不是整数的情况, resharper 显示此消息的唯一原因是因为您正在比较没有 th 的浮点数(关于连续)您需要做的是将图片的高度和宽度属性更改为整数(首先没有理由为什么图像宽度/高度属性类型会是浮点数) , 这样做而不是遵循 resharper 的自动修复。

    【讨论】:

    • 这并不能真正回答关于合理公差的问题。图片/图像类型可以并且确实具有双重类型属性,即使对于宽度和高度也是如此。所有 WPF 控件都使用双精度 x、y、宽度和高度,这也包括 Image 类。
    • 它确实回答了这个问题,正如我所写的,换句话说,在这种情况下,合理的容差是 0 ,在这种情况下你不需要容差,因为它不是连续值、任何图像类型或控件使用 double 属性在其内部实现中将其转换为 int ,没有半个像素那么薄,因为上面的代码是“内部实现”,只需将属性保存在整数中即可使其正常工作。
    猜你喜欢
    • 2015-08-05
    • 1970-01-01
    • 1970-01-01
    • 2018-10-08
    • 1970-01-01
    • 2021-09-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多