Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why the digits after decimal are all zero?

I want to perform some calculations and I want the result correct up to some 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 output:

79577232813771760.000000000000

I even used setprecision(), but same answer rather in exponential form.

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

prints

7.95772328138e+16

Used long double also, but in vain.

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

If so, what can be done to get the answer precisely?

like image 818
Sunny Avatar asked Apr 10 '13 16:04

Sunny


2 Answers

A double has only about 16 decimal digits of precision. Everything after the decimal point would be nonsense. (In fact, the last digit or two left of the point may not agree with an infinite-precision calculation.)

Long double is not standardized, AFAIK. It may be that on your system it is the same as double, or no more precise. That would slightly surprise me, but it doesn't violate anything.

like image 90
Andrew Lazarus Avatar answered Sep 29 '22 19:09

Andrew Lazarus


You need to read Double-Precision concepts again; more carefully.

The double has increased precision by using 64 bits.
Stuff before the decimal is more important than that after it.
So, when you have a large integer part, it will truncate the lower precision -- this is being described to you in various answers here as rounding off.


Update:
To increase precision, you'll need to use some library or change your language.
Check this other question: Best coding language for dealing with large numbers (50000+ digits)

Yet, I'll ask you to re-check your intent once more.

  • Do you really need 12 decimal places for numbers that have really high values
    (over 10 digits in the integer part like in your example)?
  • Maybe you won't really have large integer parts
    (in which case such code should work fine).
  • But if you are tracking a value like 10000000000.123456789,
    I am really interested in exactly which application you are working on (astronomy?).
  • If the integer part of your values is some way under 10000, you should be fine here.

Update2:
IF you must demonstrate the ability of a specific formula to work accurately within constrained error limits, the way to go is fixing the processing of your formula such that the least error is introduced.

Example,

  • If you want to do say, (x * y) / z
  • it would be prudent to try something like max(x,y)/z * min(x,y)
  • rather than, the original form which may overflow after (x * y), loosing precision if that did not fit in the 16 decimals of double

If you had just 2 digit precision,

.               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 intent of your contest.

like image 29
nik Avatar answered Sep 29 '22 20:09

nik