Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Doubles and Arithmetic

I compile and run this code with MSVC2008

long double x = 111111111;
long double y = 222222222;
long double Z = x * y;

cout << z << endl;

When I debug, z equals

24691357975308640

Mathematically z should be

24691357975308642

What's going on ?

like image 852
Jonas Avatar asked Dec 13 '25 01:12

Jonas


2 Answers

Doubles are only precise to around 16 digits. If I counted right, then you have 17 digits, and are correct up to 16. If you want to do this kind of math, and will only have integers, then use ints. For a number that large, you will need to use uint64_t.

like image 186
PearsonArtPhoto Avatar answered Dec 14 '25 18:12

PearsonArtPhoto


Nothing is going on. Doubles have a finite amount of precision, and for that precision the value that you obtain is correct. It is an unfortunate shortcoming of the way you chose to print the value that information about the precision (i.e. the significant digits) was lost.

For example, for a 1+11+(1)+52 float (see here), we have 53 bits of precision, giving us 53 × log102 de­ci­mal digits of precision, i.e. 15. So we only print 15 digits:

#include <iomanip>
#include <iostream>

std::cout << std::setfill('0') << std::setprecision(15) << std::scientific
          << Z << std::endl;

The result is:

2.469135797530864e+16

Now we made the precision manifest, and the result is indeed correct at that precision.

If you don't like the magic 15 in the code, you should #include <limits> and use:

std::numeric_limits<decltype(Z)>::digits10
like image 41
Kerrek SB Avatar answered Dec 14 '25 16:12

Kerrek SB



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!