Approx Epsilon Usage & Constructors
Hi,
As I often deal with floating point values, I tend to use the Approx class quite often. Now, let's consider the below example. The CHECK will pass even though the true absolute difference is 0.00001 = 1.e-05. If we use Approx(testValue).epsilon(1.e-12) then the test will give CHECK(false).
const double testValue = 0.98765;
const double trueValue = 0.98766;
CHECK(Approx(testValue) == trueValue); // this gives CHECK(true)Usually, I deem values to be correct if they pass a certain absolute threshold:
abs(lhs - rhs) < epsilon; // (1)However, doctest implements this formula:
abs(lhs - rhs) < epsilon * ( scale + max(abs(lhs), abs(rhs)) ); // (2)which is slightly different.
Questions:
Why does
epsilondefault tostd::numeric_limits<float>::epsilon()*100=1.2e-05as opposed tostd::numeric_limits<double>::epsilon()*100=2.2e-14. I am asking since all comparisons are based ondoublevalues, and notfloatvalues. Personally, I find1.2e-05to be quite a low threshold.In
catch2one can writeApprox(testValue).margin(1.e-12).epsilon(0)to exactly achieve method(1)above. (a) Is there benefit in adding extra settings to doctest'sApproxclass? So that one can achieve both method(1)and(2)? (b) In order to avoid these long factory-like expressions (ascatch2has them), one could allow to add them via an additional constructor. E.g.Approx(double value, double epsilon, double margin)would help shorten the expression toApprox(testValue, 1.e-12, 0).
Happy to help write the code for this, but wanted to get some feedback on my questions first.
Source: doctest/doctest