此图像缩放代码的合理 Epsilon/Tolerance 值是多少?
What is a reasonable Epsilon/Tolerance value for this image scaling code?
Resharper 要我更改此现有代码:
if (pic.Height == oldH)
{
pic.Height *= fX;
}
...为此:
if (Math.Abs(pic.Height - oldH) < TOLERANCE)
{
pic.Height *= fX;
}
...因为“浮点数与相等运算符的比较。舍入值时可能会丢失精度”
"guttersnipe"(将鼠标悬停在代码左侧的 Resharper 的灯泡图标上时弹出的工具提示)是“修复浮点数比较。比较与 Epsilon 的差异"
代码已经运行了几个月没有问题;我很高兴通过使用 Resharpened 版本的代码让它变得更好,但是: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 进行比较。
如你所知,一个浮点数可以保存一个真正的连续值,在大多数情况下,当比较连续值时,如果它们之间的距离小于一个小阈值(epsilon),则这些值被认为是相等的,显然整数不是这种情况,
resharper 显示此消息的唯一原因是因为您正在比较没有 th 的浮点数(连续),您需要做的是更改图片的高度和宽度属性为整数(图像width/height属性类型没有理由首先是浮点数) ,
这样做而不是遵循 resharper 的自动修复。
在网上做了一些研究后,我使用这段代码来比较双打。
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
Resharper 要我更改此现有代码:
if (pic.Height == oldH)
{
pic.Height *= fX;
}
...为此:
if (Math.Abs(pic.Height - oldH) < TOLERANCE)
{
pic.Height *= fX;
}
...因为“浮点数与相等运算符的比较。舍入值时可能会丢失精度”
"guttersnipe"(将鼠标悬停在代码左侧的 Resharper 的灯泡图标上时弹出的工具提示)是“修复浮点数比较。比较与 Epsilon 的差异"
代码已经运行了几个月没有问题;我很高兴通过使用 Resharpened 版本的代码让它变得更好,但是: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 进行比较。
如你所知,一个浮点数可以保存一个真正的连续值,在大多数情况下,当比较连续值时,如果它们之间的距离小于一个小阈值(epsilon),则这些值被认为是相等的,显然整数不是这种情况, resharper 显示此消息的唯一原因是因为您正在比较没有 th 的浮点数(连续),您需要做的是更改图片的高度和宽度属性为整数(图像width/height属性类型没有理由首先是浮点数) , 这样做而不是遵循 resharper 的自动修复。
在网上做了一些研究后,我使用这段代码来比较双打。
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