这不是重复的问题。问题中有答案。希望能对您有所帮助。
有两个doubles
,其值与小数点相同。
(对不起,这不是一个好案例。因为有时它会返回false
,但我找不到该案例。如果您尝试这种情况,则可能没有任何问题。所以不要浪费时间进行测试。)
double a = 0.70448;
double b = 0.70441;
我只想将它们与小数点后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
。我非常了解这是一个浮动的问题,所以我想知道是否有任何优雅的解决方案可以将它们进行比较。
更新:
我尝试将其乘以整数进行比较。但是,对于此解决方案,我需要处理double infinity和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
}
如果double中的一个大于int max或infinity,则抛出 System.OverflowException
。另外,这不是优雅比较双精度方式。
重要:
我不会舍入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;
}
答案 0 :(得分:1)
如果您使用Math.Round
方法将a
和b
舍入到小数点后四位,a
(0.7045
)将始终大于{{1 }}(b
):
0.7044
如果要截断值,则需要注意以下事实:并非所有分数都可以在const double a = 0.70448;
const double b = 0.70441;
if (Math.Round(a, 4) > Math.Round(b, 4))
...
中准确表示。如果要“精确”截断,可以考虑将double
值转换为double
,截断string
,然后将截断的string
值转换回{{1 }}。像这样:
string
用法:
double
很明显,如果您不希望像在聊天中所说的那样出现任何“浮动问题”,则不能使用浮点数据类型。
答案 1 :(得分:0)
您要截断而不是舍入:
double a = Math.Truncate(100 * 0.70448) / 100;
double b = Math.Truncate(100 * 0.70441) / 100;
if (a > b)
{
// ...
}
请注意,根据@ mm8的注释,分数不能准确地表示在double
中。