比较两位小数

我想比较c#中的两个小数,但有一些误差。 任何人都可以指出以下代码的问题。 请注意,我对6个小数位感兴趣,之后我可以忽略这些值。

var valOne = decimal.Round(valueOne, 6); var valTwo = decimal.Round(valueTwo, 6); var difference = Math.Abs(valOne - valTwo); if (difference > 0.0000001m) { Console.WriteLine("Values are different"); } else { Console.WriteLine("Values are equal"); } 

或者,还有更好的方法。

如果要将值四舍五入到小数点后6位,那么您的epsilon值太小。 两个值可以不同的最小量是0.000001。

例如:

 var valOne = Decimal.Round(1.1234560M, 6); // Gives 1.123456 var valTwo = Decimal.Round(1.1234569M, 6); // Gives 1.123457 if (Math.Abs(valOne - valTwo) >= 0.000001M) { Console.WriteLine("Values differ"); } else { Console.WriteLine("Values are the same"); } 

以下为我工作:

 var valueOne = 1.1234563M; var valueTwo = 1.1234567M; var diff = Math.Abs(valueOne - valueTwo); //Console.WriteLine(diff); if(diff > 0.0000003M) { Console.WriteLine("diff"); } else { Console.WriteLine("equal"); } 

以上将显示“差异”。

如果更改为var valueOne = 1.1234565M; 差值将小于阈值,因此它将显示“相等”。

然后根据您的需要进行RoundTruncate

编辑:@tangokhi刚刚注意到你的答案! 你是对的..忽略我的回复。

修正拼写错误“var valTwo = decimal.Roung(valueTwo,6);” 它应该是decimal.Round(….

您还可以使用Decimal.Equals(dec1,dec2)或Decimal.Compare(dec1,dec2)比较小数

你可以做一个function,做这样的事情

 public static bool Check(decimal first, decimal second, decimal margin) { return Math.Abs(first - second) <= margin; } 

它将返回true或false,具体取决于值是否小于或等于

我想如果我不使用Round那么这个解决方案很好。

 var valOne = 1.1234560M; // Decimal.Round(1.1234560M, 6); Don't round. var valTwo = 1.1234569M; // Decimal.Round(1.1234569M, 6); Don't round if (Math.Abs(valOne - valTwo) >= 0.000001M) // Six digits after decimal in epsilon { Console.WriteLine("Values differ"); } else { Console.WriteLine("Values are the same"); } 

如上所述,对于六位小数,两位小数可以不同的最小量是0.000001M。 可以安全地忽略任何小于此的东西。 我认为这个解决方案很好,但如果有人认为我错过了什么,我感谢你的帮助。

谢谢大家

这个答案基于这里的最高投票: C#的浮点比较函数

如图所示,有一些边缘情况需要考虑,这就不能进行直接比较。 基本上是因为小数可能相等,但实际上并没有被代码视为相等,即

 float a = 0.15 + 0.15 float b = 0.1 + 0.2 if (a == b) { ... } // can be false! if (a >= b) { ... } // can also be false! 

您必须指定要比较数字的距离。 在链接术语中给出的答案是作为“Epsilon”,但他们没有详细说明是否是placevalues,范围,或者只是给出的数字的增量。

以下函数中的“Epsilon”将比较给定程度的差异。 例如,如果您想使用上面的示例并使其恢复为真,则您希望在0.1之间进行比较,而不是0.01,就像在比较0.30到0.3时默认情况下那样。

  public static bool nearlyEqual(double a, double b, double epsilon) { double absA = Math.Abs(a); double absB = Math.Abs(b); double diff = Math.Abs(a - b); if (a == b) { // shortcut, handles infinities return true; } else if (a == 0 || b == 0 || diff < Double.Epsilon) { // a or b is zero or both are extremely close to it // relative error is less meaningful here return diff < epsilon; } else { // use relative error return diff / (absA + absB) < epsilon; } } 

假设您有一个带有项目ID和浮点小数(双)数的项目字典,就像一堆纬度......

  Dictionary cityLatPoints = new Dictionary(); 

你想知道纬度是否接近其中一个点...这就是你如何做到这一点:

 double epsilon = 0.000005; List possLatCityIds = new List(); // stores your matching IDs for later double dblLat = 39.59833333; // hard-coded value here, but could come from anywhere // Possible Latitudes foreach (KeyValuePair kvp in cityLatPoints) { if (nearlyEqual(kvp.Value, dblLat, epsilon)) { //Values are the same or similar possLatCityIds.Add(kvp.Key); // ID gets added to the list } } 

对于给出的示例,它看起来像这样:

 decimal valOne = decimal.Round(valueOne, 6); decimal valTwo = decimal.Round(valueTwo, 6); double dblOne = Convert.ToDouble(valOne); double dblTwo = Convert.ToDouble(valTwo); double epsilon = 0.0000001; if (nearlyEqual(dblOne, dblTwo, epsilon)) { Console.WriteLine("Values are equal"); } else { Console.WriteLine("Values are different"); }