Why are the digits after the decimal number zero?

I want to do some calculations, and I want the result to be correct to decimal places, say 12. So I wrote a sample:

#define PI 3.1415926535897932384626433832795028841971693993751 double d, k, h; k = 999999/(2*PI); h = 999999; d = PI*k*k*h; printf("%.12f\n", d); 

But it gives the result:

 79577232813771760.000000000000 

I even used setprecision (), but the same answer is more likely in exponential form.

 cout<<setprecision(12)<<d<<endl; 

prints

 7.95772328138e+16 

Used a long double, but in vain.

Now is there any way besides storing the integer part and fractional part separately in long long types?

If so, what can be done to get an answer for sure?

+4
source share
5 answers

The double has only about 16 decimal digits of precision. Anything after the decimal point would be nonsense. (In fact, the last digit or two to the left of the point may not coincide with the calculation with infinite accuracy.)

Long double is not standardized, AFAIK. Perhaps in your system this is the same as double, or no more accurate. It will surprise me a little, but it does not break anything.

+6
source

You need to read Double-Precision again; more thoroughly .

double has increased accuracy using 64 bits.
The thing before decimal is more important than after it. Thus, when you have a large integer part, it truncates the lower accuracy - this is described to you in various answers here as rounding off .


Update :
To increase accuracy, you will need to use some library or change your language.
Check out this other question: Best coding language for working with large numbers (50,000 + digits)

However, I will ask you to once again verify your intentions.

  • You really need 12 decimal places for numbers that have really high values
    (more than 10 digits of the integer part, as in your example)?
  • You may not really have large integer parts
    (in this case, such code should work fine).
  • But if you are tracking a value like 10000000000.123456789 ,
    I'm really curious what application you are working in (astronomy?).
  • If the integer part of your values ​​is under the sign 10000 , you should be fine.

Update2 :
IF you must demonstrate the ability of a particular formula to work exactly within the limited error limits, the way to go is to correct the processing of your formula so that the smallest error is introduced.

Example

  • If you want to say (x * y) / z
  • It would be wise to try something like max(x,y)/z * min(x,y)
  • rather than the original form, which may overflow after (x * y) , losing precision if it does not match 16 decimal places double

If you had only double-digit accuracy,

 . 2-digit regular-precision `42 * 7 290 297 (42 * 7)/2 290/2 294/2 Result ==> 145 147 But ==> 42/2 = 21 21 * 7 = 147 

This is probably the goal of your competition.

+4
source

The double precision double format used by most computers can only contain 16 digits, after which you will get rounding. See http://en.wikipedia.org/wiki/Double-precision_floating-point_format

+1
source

Floating point values ​​have a range of digits. Just because your β€œPI” value has six times more digits than double support does not change the way the equipment works.

A typical (IEEE754) double will produce approximately 15-16 decimal places. Be it 0.12345678901235, 1234567.8901235, 12345678901235 or 12345678901235000000000, or some other option.

In other words, yes, if you calculate your calculation EXACTLY, you will get many decimals, because pi never ends. On the computer, you get about 15-16 digits, no matter what input values ​​you use - everything that changes is the place where the decimal place is in this sequence. To get more, you need "support for a large number", for example, the Gnu Multipression (GMP) library.

+1
source

You are looking for std::fixed . This suggests that ostream does not use exponential form.

 cout << setprecision(12) << std::fixed << d << endl; 
0
source

All Articles