How to distinguish zero from a very small number in floating form

I am going to develop a scientific calculator. My question is: How can I distinguish a zero result from very small numbers using a floating point number?

For example, for 0.3 - 0.2 - 0.1, the result is something like 1E-19, which is not a pure zero (of course, the problem of accuracy). I want to print the result (0.0). Therefore, I use EPSILON to compare with zero.

The problem is that to calculate: 3E-19 - 2E-19, the result should be 1E-19. I have to print exactly the result (albeit small) of 1E-19. But if I still use the EPSILON comparison, the result will be zero.

So, again, my question is: how can I check for zero and very small numbers?

+5
source share
4 answers

This is essentially impossible if you are using a binary floating-point data type.

Instead, if you need precise control over numerical precision and rounding, you should use a decimal number library such as GNU Multiprecision (GMP) or Boost.Multiprecision .

+5
source

You said that 0.3-0.2-0.1 is not 0, but rather 1E-19. In fact, it already floats (0.3) -float (0.2) -float (0.1), which is no longer 0. If you do not explicitly check whether 0.3 can be encoded in float or double losslessly, then there is no way check, get after calculation due to an operand error or a really small number.

+2
source

If you have not met him this page , this is basically the last word compared to floating point.

However, I think your problem comes down to understanding what precision is needed based on the operands and operations that were performed. You can judge this from the largest ULP between operands. If there is a large ULP between the operands, you may need to display a more accurate answer (up to the accuracy limit available in floating views, please). It might be worth experimenting with something like that.

0
source

Of course, scientific calculator will face this problem with such equations as 1.0 - 7*(1.0/7.0) , regardless of whether the code uses a double (binary FP) or a library of high precision base 2, 10.

Use the decimal floating point library to minimize the occurrence of rounding errors with decimal inputs, e.g. 0.1, 0.2, 0.3 .

“I want to print the result (0.0). Therefore, I use EPSILON to compare with zero.” Since FP numbers have a logarithmic distribution.

Consideration: Allow the user to control the format of the displayed output. Essentially, this allows the user to install EPSILON. For instance. "%.17f" and 0.3 - 0.2 - 0.1 will "%.17f" to zero.

0
source

Source: https://habr.com/ru/post/1247399/


All Articles