Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Precision difference when printing Python and C++ doubles

I'm currently marvelling over this:

C++ 11

#include <iostream>
#include <iomanip>
#include <limits>

int main()
{
  double d = 1.305195828773568;
  std::cout << std::setprecision(std::numeric_limits<double>::max_digits10) << d << std::endl;
  // Prints  1.3051958287735681
}

Python

>>> repr(1.305195828773568)
'1.305195828773568'

What's going on, why the extra 1 in C++?

So far I thought that C++ and Python use the same 64 bit IEEE doubles under the hood; both formatting functions are supposed to print the full precision.

like image 995
nh2 Avatar asked Sep 03 '15 23:09

nh2


People also ask

How precise are doubles C++?

The C++ double should have a floating-point precision of up to 15 digits as it contains a precision that is twice the precision of the float data type. When you declare a variable as double, you should initialize it with a decimal value. For example, 3.0 is a decimal number.

Does Python Use single or double precision?

Python uses the float class to represent the real numbers. CPython implements float using C double type. The C double type usually implements IEEE 754 double-precision binary float, which is also called binary64. Python float uses 8 bytes (or 64 bits) to represent real numbers.

Why does Python use float instead of double?

These are almost the same - two names are provided because in some programming languages there are differences between float and double types. There are no such differences in python, but note that float is built in to python, while double comes from numpy, and hence is slightly different.

How do you get 2 decimal places in Python?

In Python, to print 2 decimal places we will use str. format() with “{:. 2f}” as string and float as a number. Call print and it will print the float with 2 decimal places.


2 Answers

you can force python to print the 1 as well (and many more of the following digits):

print('{:.16f}'.format(1.305195828773568))
# -> 1.3051958287735681

from https://docs.python.org/2/tutorial/floatingpoint.html:

>>> 7205759403792794 * 10**30 // 2**56
100000000000000005551115123125L

In versions prior to Python 2.7 and Python 3.1, Python rounded this value to 17 significant digits, giving ‘0.10000000000000001’. In current versions, Python displays a value based on the shortest decimal fraction that rounds correctly back to the true binary value, resulting simply in ‘0.1’.

"print the full precision" is hard to do: what is the full precision? the representation of floats is binary; only fractions of powers of 2 can be represented exactly (to full precision); most decimal fractions can not be represented exactly in base 2.

but the float in the memory will be the same for python and c++; it is just the string representation that differs.

like image 57
hiro protagonist Avatar answered Sep 20 '22 10:09

hiro protagonist


When the format ends up using fixed point notation, the precision() specifies the number of fractional digits. Since there is an additional non-fractional digits in your example one more than those which can be safely represented is created.

When using scientific notation, the total number of digits is counted and you'll get the same digits as the original (plus an exponent, of course). The C and C++ options for formatting floating point numbers are actually fairly bad. In particular, there is no option which lets the formatter decide the appropriate number of digits although the underlying algorithm can actually determine these.

like image 34
Dietmar Kühl Avatar answered Sep 18 '22 10:09

Dietmar Kühl