【发布时间】:2018-06-25 13:56:29
【问题描述】:
这不是重复的问题。问题中有一个答案。希望对您有所帮助。
有两个doubles 具有相同的小数值。
(对不起,这不是一个好案例。因为它有时会返回false,但我找不到案例。如果你尝试这个案例,它可能没有任何问题。所以不要浪费时间测试它。)
double a = 0.70448;
double b = 0.70441;
我只想将它们与 4 位小数进行比较。
我有这个辅助函数可以先将它们向下舍入到小数点后 4 位。
public static double RoundDown(this double value, int decimals)
{
var multiplier = Math.Pow(10, decimals);
return Math.Floor(value * multiplier) / multiplier;
}
然后我想检查a 是否大于b,如下所示:
RoundDown(a, 4) > RoundDown(b, 4)
有时,在某些情况下,即使它们看起来相等,它也会返回 true。我非常了解这是浮动问题,所以我想知道是否有任何优雅的解决方案来比较它们。
更新:
我试图将它相乘并以整数比较它们。但是,对于这个解决方案,我需要处理双无穷大和 NAN。
private static CompareResult Compare(double a, double b, double decimals = 0)
{
var multiplier = Math.Pow(10, decimals);
var aInt = Convert.ToInt32(a * multiplier);
var bInt = Convert.ToInt32(b * multiplier);
return aInt > bInt ? CompareResult.Greater : aInt < bInt ? CompareResult.Less : CompareResult.Equal;
}
private enum CompareResult
{
Greater,
Less,
Equal
}
System.OverflowException 如果 double 之一大于 int max 或 infinity 则抛出。此外,这不是比较双倍的优雅方式。
重要提示:
我不会用 x 有效数字四舍五入。我已经在我的问题中提供了这个解决方案,我的问题是:即使向下舍入到 x 有效数字,比较它们时也会返回 true。
再次
我没有找到将双精度数舍入或截断为 x 有效数字的方法。这部分我没有问题。
回答
感谢@m88 的回答。但它仍然无法解决我的问题。 我终于使用 sigma 解决了这个问题。 (参考:http://forums.codeguru.com/showthread.php?506300-float-double-value-comparison-significant-figures。)
感谢一些人误解了问题并将其投票为重复问题。我不能为面临同样问题的其他人发布我的答案。所以我在我的问题中发布了答案。我希望它可以帮助其他人。
public static int CompareTo(this double value1, double value2, int decimals)
{
var diff = value1 - value2;
var sigma = Math.Pow(10, -decimals - 1);
return Math.Abs(diff) < sigma ? 0 : diff > 0 ? 1 : -1;
}
【问题讨论】:
-
@Equalsk 请仔细阅读我的问题。我已经告诉过你将双精度数舍入到 x 有效数字的方法。我想要的是正确比较它们。
-
请仔细阅读链接的副本,而不仅仅是标题。它演示了 truncation,这是您在 rounding 之后所追求的。
-
@Equalsk 我已经读过了。我想要的是正确比较,而不是截断或舍入。检查这个:forums.codeguru.com/…
-
@Equalsk 或者你想说问题出在向下舍入方法上?还是 Math.Floor 导致比较失败?
-
@Servy 无论如何,我已经一次又一次地阅读了可能重复的问题。首先,它没有公认的答案。其次,投票最多的答案已经是我当前的四舍五入解决方案。请仔细准备我的问题,而不是只阅读第一段。我想比较它们,但不想舍入/截断它们。