如何正确比较C#中的十进制值?
我来自C ++的背景,我知道你不能准确地比较花车的平等。 对于C#,我只是假设同样的政策适用于十进制值,或一般的任何浮点值。
基本上,我有两个十进制值,如果它们不相等,我需要执行一些操作。 例如:
decimal value1, value2; // Assume value1 and value2 are set somewhere to valid values. if( value1 != value2 ) { // Do something }
如果这不能按预期的那样工作,我愿意接受一个解决scheme,与误差范围进行平等比较,比如.00001或类似的。 这个问题的build议解决scheme是什么?
您的代码将按预期工作。 C#的decimal
被优化为非常准确的表示基数为10的数字,所以如果这就是你比较(金钱,…),一切都应该没问题。
下面是关于Jon Skeet小数的准确性的一个非常明确的解释:
.NET中decimal,float和double的区别?
我正在研究类似的东西,但是精确度不是很高,而是写了一些Float的扩展。 这可以很容易地适应任何types。 我有一个复杂的比较系列,这使得它很好,可读。
/// <summary> /// A set of extensions to allow the convenient comparison of float values based on a given precision. /// </summary> public static class FloatingPointExtensions { /// <summary> /// Determines if the float value is less than or equal to the float parameter according to the defined precision. /// </summary> /// <param name="float1">The float1.</param> /// <param name="float2">The float2.</param> /// <param name="precision">The precision. The number of digits after the decimal that will be considered when comparing.</param> /// <returns></returns> public static bool LessThan(this float float1, float float2, int precision) { return (System.Math.Round(float1 - float2, precision) < 0); } /// <summary> /// Determines if the float value is less than or equal to the float parameter according to the defined precision. /// </summary> /// <param name="float1">The float1.</param> /// <param name="float2">The float2.</param> /// <param name="precision">The precision. The number of digits after the decimal that will be considered when comparing.</param> /// <returns></returns> public static bool LessThanOrEqualTo(this float float1, float float2, int precision) { return (System.Math.Round(float1 - float2, precision) <= 0); } /// <summary> /// Determines if the float value is greater than (>) the float parameter according to the defined precision. /// </summary> /// <param name="float1">The float1.</param> /// <param name="float2">The float2.</param> /// <param name="precision">The precision. The number of digits after the decimal that will be considered when comparing.</param> /// <returns></returns> public static bool GreaterThan(this float float1, float float2, int precision) { return (System.Math.Round(float1 - float2, precision) > 0); } /// <summary> /// Determines if the float value is greater than or equal to (>=) the float parameter according to the defined precision. /// </summary> /// <param name="float1">The float1.</param> /// <param name="float2">The float2.</param> /// <param name="precision">The precision. The number of digits after the decimal that will be considered when comparing.</param> /// <returns></returns> public static bool GreaterThanOrEqualTo(this float float1, float float2, int precision) { return (System.Math.Round(float1 - float2, precision) >= 0); } /// <summary> /// Determines if the float value is equal to (==) the float parameter according to the defined precision. /// </summary> /// <param name="float1">The float1.</param> /// <param name="float2">The float2.</param> /// <param name="precision">The precision. The number of digits after the decimal that will be considered when comparing.</param> /// <returns></returns> public static bool AlmostEquals(this float float1, float float2, int precision) { return (System.Math.Round(float1 - float2, precision) == 0); } }
我想这会解决你的问题。
基本上有一个decimal.compare方法。
编辑:这可能是更好的方法:
Decimal.Equals
编辑2:如果你可以直接比较上面的build议,这可能会更有效率。 我会离开这个,因为它可能是有兴趣的。
我同意其他的答案,但我遇到了一个问题,一个“真正的”服务器端小数得来自一个来自JSON /浏览器(并且一定是一个浮点数)。
我结束了这个代码在小数点后面舍入到2位数字 ,在我的情况下足够精确:
if (Decimal.Round(serverTotalPrice, 2) != Decimal.Round(request.TotalPrice, 2)) { throw new ArgumentException("The submitted Total Price is not valid"); }