评估如果两个双打相等基于给定的精度,而不是某一固定的公差范围内 [英] Evaluate if two doubles are equal based on a given precision, not within a certain fixed tolerance

查看:149
本文介绍了评估如果两个双打相等基于给定的精度,而不是某一固定的公差范围内的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我运行NUnit的测试,以评估一些已知的测试数据和计算结果。这些数字是浮点双打,所以我不希望他们是完全相等的,但我不知道如何将它们视为等同于一个给定的精度。

I'm running NUnit tests to evaluate some known test data and calculated results. The numbers are floating point doubles so I don't expect them to be exactly equal, but I'm not sure how to treat them as equal for a given precision.

在NUnit的,我们可以用一个固定的容差比较:

In NUnit we can compare with a fixed tolerance:

double expected = 0.389842845321551d;
double actual   = 0.38984284532155145d; // really comes from a data import
Expect(actual, EqualTo(expected).Within(0.000000000000001));

和对于低于零的数字工作正常,但随着数量的增长公差真的需要改变。所以我们一直关心的相同数量的精确数字。

and that works fine for numbers below zero, but as the numbers grow the tolerance really needs to be changed so we always care about the same number of digits of precision.

具体而言,本次测试失败:

Specifically, this test fails:

double expected = 1.95346834136148d;
double actual   = 1.9534683413614817d; // really comes from a data import
Expect(actual, EqualTo(expected).Within(0.000000000000001));



当然还有更大的数字失败,宽容..

and of course larger numbers fail with tolerance..

double expected = 1632.4587642911599d;
double actual   = 1632.4587642911633d; // really comes from a data import
Expect(actual, EqualTo(expected).Within(0.000000000000001));



什么是评估两个浮点数是与给定精度等于正确的方法是什么? ?是否有一个内置的方式在NUnit的做到这一点。

What's the correct way to evaluate two floating point numbers are equal with a given precision? Is there a built-in way to do this in NUnit?

推荐答案

从MSDN:

默认情况下,双值包含的精度小数点后15位,虽然最大的17位内部维护。

By default, a Double value contains 15 decimal digits of precision, although a maximum of 17 digits is maintained internally.

让我们假设15,然后。

Let's assume 15, then.

所以,我们可以说,我们要宽容要达到相同的程度。

So, we could say that we want the tolerance to be to the same degree.

多少确切的数字我们小数点后有哪些?我们需要知道从小数点最显著位的距离,对不对?的幅度。我们可以用一个log10的得到这个。

How many precise figures do we have after the decimal point? We need to know the distance of the most significant digit from the decimal point, right? The magnitude. We can get this with a Log10.

然后,我们需要10 ^精密分1绕过我们想要的精确值。

Then we need to divide 1 by 10 ^ precision to get a value around the precision we want.

现在,你需要做更多的测试案例,比我有,但是这似乎工作:

Now, you'll need to do more test cases than I have, but this seems to work:

  double expected = 1632.4587642911599d;
  double actual = 1632.4587642911633d; // really comes from a data import

  // Log10(100) = 2, so to get the manitude we add 1.
  int magnitude = 1 + (expected == 0.0 ? -1 : Convert.ToInt32(Math.Floor(Math.Log10(expected))));
  int precision = 15 - magnitude ;

  double tolerance = 1.0 / Math.Pow(10, precision);

  Assert.That(expected, Is.EqualTo(actual).Within(tolerance));



现在已经晚了 - 有可能是一个疑难杂症在这里了。我测试了对你的三组测试数据和各过去了。更改 pricision 16 - 震级导致测试失败。将其设置为 14 - 震级显然造成它传递的耐受性较大

It's late - there could be a gotcha in here. I tested it against your three sets of test data and each passed. Changing pricision to be 16 - magnitude caused the test to fail. Setting it to 14 - magnitude obviously caused it to pass as the tolerance was greater.

这篇关于评估如果两个双打相等基于给定的精度,而不是某一固定的公差范围内的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆