1

There are a lot of articles, PhD publications, books and question here on this topic, still my question will be pretty straightforward.

How can we improve this or workaround without writing dozens of ifs?

Suppose I have 2 doubles;

double d1 = ..; double d2 = ..; 

The most naïve think we can try to do is to try if(d1==d2) // baaaad!!!, as we know we can fail on precision mismatches on very close values.

Second naïve thing can be if(std::abs(d1-d2) < std::numeric_limits<double>::epsilon())
This still fails for relatively big doubles as std::numeric_limits<double>::epsilon() described as follows:

Returns the machine epsilon, that is, the difference between 1.0 and the next value representable by the floating-point type T

Which for double is 0.00000000000000022204

So I came up with this:

double epsilon = std::max(d1,d2)/1E14; // I am ok with precision mismatch after 14th digit, regardless how big the number is.

The problem here is that for small numbers this fails, for instance this prints 0.00..00

double d = 1E-7; std::cout<<std::fixed<<std::setprecision(20)<< d/1E14; 

So the question will be is there a generic solution/workaround for this, or I should write dozens of ifs to decide my denomination properly in order not to overkill the precicion?

3
  • 9
    There is no single, universal, solution that produces ideal results in every possible situation. The epsilon, for each particular comparison, must be carefully chosen based on the individual and specific circumstances of the calculation that produces it. Commented Apr 28, 2022 at 1:12
  • If someone knew about a domain-independent way to generically handle these issues in a way that satisfied everyone, we'd be using it already. It's hard to say if "dozens of ifs" will or won't be required in your case, but you will have to think about what magnitudes you're working with and what precision you need for the computations you're doing; there's no one-size-fits-all solution. Commented Apr 28, 2022 at 1:14
  • Knuth says: stackoverflow.com/a/253874/4641116 Commented Apr 28, 2022 at 1:26

1 Answer 1

1

So the question will be is there a generic solution/workaround for this

There will not be a universal solution for finite precision floating point that would apply to all use cases. There cannot be, because the correct threshold is specific to each calculation, and cannot generally be known automatically.

You have to know what you are comparing and what you are expecting from the comparison. Full explanation won't fit in this answer, but you can find most information from this blog: https://randomascii.wordpress.com/2012/02/25/comparing-floating-point-numbers-2012-edition/ (not mine).


There is however a generic solution/workaround that side-steps the issue: Use infinite precision arithmetic. The C++ standard library does not provide an implementation of infinite precision arithmetic.

Sign up to request clarification or add additional context in comments.

1 Comment

Infinite-precision arithmetic is impossible to realize. Was symbolic computation the intended term? What is available are arbitrary-precision libraries, but they do not fundamentally change the problem, just kick the can down the road towards smaller epsilons.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.