Mathematical division needs

47

On the Windows calculator: 9 / 3,0001 = 2,999 ...
In my program: 9 / 3,0001 = 3;

I would like to get this level of precision using C.

See excerpts from my program:

double op(double num1, double num2, char c)
{
      if(c == '/')
      {
        if(num2 == 0)
        {
            printf("operacao nao pode ser realizada");

            exit(1);
        }
        else
            num1 = (num1)/num2;
      }

      ...

      printf("%.3lf\n", num1);

      return num1;
}

int main()
{
   double num1,num2;

   char c;

   scanf("%lf", &num1);

   scanf("%lf", &num2);

   scanf(" %c", &c);

   num1 = op(num1, num2, c);

   ...

   return 0;
}

How to do it?

    
asked by pcccj 25.10.2014 в 18:23
source

4 answers

32

If you really want accurate precision for floating-point operations, you will have to use a library such as GMP . The @Maniero user gave a reasonable introduction on where to find more information about floating point (which is not a C language problem per se, but rather how floating point is implemented inside the processor).

The GNU Multi-Precision Library GMP library is an open source library for working with numbers with arbitrary precision, whether integer, fractional or floating-point.

It's very simple to work with, and the documentation is very complete, and the library is available for all major platforms and architectures.

More information at The GNU Multiple Precision Arithmetic Library .

    
answered by 25.10.2014 / 18:59
source
30

There are several posts about this here on the site ( this one for example ). You can not do this in any numbered language with binary floating point which is the case of float and double . You need to assemble a data structure or handle the data in a different way. This is usually the decimal or monetary form. Usually numbers are treated as if they were integers and presented with houses after the comma.

The precision obtained with binary floating point has small flaws that are well accepted in many situations and works with the advantage of being extremely fast. One of the situations in which it can not be used is when monetary values are being used. But any case where absolute precision is required.

There is nothing to solve the floating-point "problem". You can use a data with many precision decimal places that will not solve the issue.

In English (the best references on the subject):

These responses are not specific to C but the concept is the same for all languages because it is the way the processor works.

Any other way will only create an illusion that the split was done correctly.

The Windows calculator solves the issue in her programming. The software understands that precision is required and handles data in this way. Curiosity: Divide 10 by 3 and then multiply the results by 3 in the Windows calculator. Then clear everything and enter the result of the division in the hand. You can for as many houses as you want in tithe. (3,33333333333333). Multiplication by 3 gives different result. The software controls this.

    
answered by 25.10.2014 в 18:28
18

In your example, 9 / 3.0001 ~ 2.99990000333322222592

So the answer rounded to 3 decimal places is actually 3,000. Your program is correct, within the limits of accuracy you have specified. If you want the result with more precision houses, you should enter it in printf :

printf("%.9lf", num1);  // com 9 casas de precisao

The double type has enough precision for about 15 significant digits (not to say that they are 15 decimal places, it depends on how many significant digits you have in the whole part of the number). If you really need more than that, then you can use another type of representation, as was suggested.

For scientific computation (in engineering, physics, other experimental sciences) it is usual to use floating-point representations (such as double ) because the data itself is generally inaccurate. Thus, the results calculated from these data also can not be very accurate. If a measurement of length was taken using a ruler with a resolution of 1 tenth of a millimeter, then the observed measurement of 3,000 m can actually be 3,00013 m or 3.000098. The observation has an error that could be +/- 0.00005 m. If you divide two measurements with this margin of error, the result is also affected by an error of the same order of magnitude. Thus, it is not meaningful to show the result with more significant numbers than the ones in the operands.

In many applications, it is rare to have data with more than a dozen significant digits, so the precision of a double is usually more than sufficient.

    
answered by 12.11.2014 в 10:47
7

If you always want exact numerical results, this is inherently impossible to achieve, using computers or not. For example, what is the "exact" square root result of 2? The result is an irrational number, so it does not have an exact numerical representation . There are many other numbers like that, an infinite number actually. :) (There are even rational numbers of infinite size, which are the periodic tithe.)

Specifically for computers, even for rational numbers it is not always possible to obtain an "exact" numerical representation. Just think of a large number, for example 1234567890 [5 reps] . It is not possible to accurately represent this number in a double variable of the C language, simply because it does not fit into a double variable ...

As far as I know, there are (at least) three ways to partially circumvent the mathematical limitations of today's computers and languages.

The first way is to use a mathematical library of "infinite precision". These libraries are widely used today because they are required for computational encryption (mainly public-key cryptography, used in "secure connections" to https:// sites). Obviously, these libraries continue to have limitations on the numerical representation of irrational numbers, but use a method for storing numbers that makes calculations possible with "big" numbers, such as 1234567890 [5 repetitions] that I cited above, or as 1024 or 2048-bit keys widely used in public key cryptography.

The second way is to work with fractional number library. In this way, it is possible to work naturally with periodic tithe and certain kinds of irrational numbers.

The other way is to work with symbolic math, where symbols are used for known irrational numbers, such as e, pi, etc. Usually some specific application is used, such as "Wolfram Mathematica" (and similar open source programs), or specific languages, such as (if I am not mistaken) R, Julia, etc. Of course there are also libraries for symbolic math for idioms like C, Python, etc., it's just a matter of looking.

    
answered by 11.09.2016 в 16:58