📜  C# 中的精度比较(1)

📅  最后修改于: 2023-12-03 15:29:46.583000             🧑  作者: Mango

C# 中的精度比较

在 C# 中比较两个数的大小和相等性时,要特别注意数值类型的精度问题。因为在计算机中使用二进制存储浮点数和小数,存在一定的精度误差。下面是在 C# 中进行精度比较的方法和注意事项。

比较浮点数

在 C# 中,float 和 double 类型的浮点数会出现精度误差。比如,两个看起来相同的浮点数可能在计算机内的存储格式不同,导致比较结果不同。

为避免浮点数精度误差带来的问题,可以使用以下方法进行比较:

  1. 使用 Math.Abs() 方法计算两个数的绝对值差值,再判断是否小于某个特定的门槛值,比如 0.0001。
float a = 0.1f;
float b = 0.2f - 0.1f;
bool isEqual = Math.Abs(a-b) < 0.0001;
Console.WriteLine(isEqual);    // 输出 true
  1. 使用 Math.Round() 方法将浮点数四舍五入至指定位数,再比较两个数的整个部分和小数部分是否相等。
double a = 0.1;
double b = 0.2 - 0.1;
bool isEqual = Math.Round(a, 2) == Math.Round(b, 2);
Console.WriteLine(isEqual);    // 输出 true
比较小数

在 C# 中比较小数时,可以使用 Decimal 类型。Decimal 类型本质上是一个定点数,没有精度误差。

decimal a = 0.1m;
decimal b = 0.2m - 0.1m;
bool isEqual = a == b;
Console.WriteLine(isEqual);    // 输出 true
注意事项
  1. 判断浮点数相等时,应该使用某个特定的门槛值来判断差值是否足够小,而不是检查差值是否恰好为 0。
float a = 3.3f;
float b = 3.3f;
bool isEqual = (a == b);    // 可能返回 false
Console.WriteLine(isEqual);

bool isEqual2 = (Math.Abs(a - b) < 0.0001);    // 推荐的比较方法
Console.WriteLine(isEqual2);
  1. 涉及到浮点数的常规算术运算也可能会导致精度误差。比如,一个浮点数除以另一个浮点数可能得到一个不精确的结果。
float x = 1.0f / 81.0f * 81.0f;
float y = 1.0f;
bool isEqual = (x == y);    // 可能返回 false
Console.WriteLine(isEqual);

float x2 = 1.0f / 81.0f;
float y2 = x2 * 81.0f;
bool isEqual2 = (x2 == y2);    // 推荐的计算方法
Console.WriteLine(isEqual2);
  1. 当使用 Decimal 类型进行小数比较时,需要特别注意使用 Decimal.Equals() 方法,而不是 == 运算符。
decimal a = 0.1m;
decimal b = 0.2m - 0.1m;
bool isEqual = a == b;    // 可能返回 false
Console.WriteLine(isEqual);

bool isEqual2 = Decimal.Equals(a, b);    // 推荐的比较方法
Console.WriteLine(isEqual2);

总之,在进行精度比较时,要注意数值类型的特性和精度误差,合理选择比较方法,避免因精度问题引发的错误。