You are running into the old problem with floating point numbers that not all numbers can be represented exactly. The command line is just showing you the full floating point form from memory.

With floating point representation, your rounded version is the same number. Since computers are binary, they store floating point numbers as an integer and then divide it by a power of two so 13.95 will be represented in a similar fashion to 125650429603636838/(2**53).

Double precision numbers have 53 bits (16 digits) of precision and regular floats have 24 bits (8 digits) of precision. The floating point type in Python uses double precision to store the values.

For example,

>>> 125650429603636838/(2**53)
13.949999999999999

>>> 234042163/(2**24)
13.949999988079071

>>> a = 13.946
>>> print(a)
13.946
>>> print("%.2f" % a)
13.95
>>> round(a,2)
13.949999999999999
>>> print("%.2f" % round(a, 2))
13.95
>>> print("{:.2f}".format(a))
13.95
>>> print("{:.2f}".format(round(a, 2)))
13.95
>>> print("{:.15f}".format(round(a, 2)))
13.949999999999999

If you are after only two decimal places (to display a currency value, for example), then you have a couple of better choices:

  1. Use integers and store values in cents, not dollars and then divide by 100 to convert to dollars.
  2. Or use a fixed point number like decimal.
Answer from Rex Logan on Stack Overflow
๐ŸŒ
Python documentation
docs.python.org โ€บ 3 โ€บ tutorial โ€บ floatingpoint.html
15. Floating-Point Arithmetic: Issues and Limitations โ€” Python 3.14.3 documentation
The float.hex() method expresses a float in hexadecimal (base 16), again giving the exact value stored by your computer: ... Since the representation is exact, it is useful for reliably porting values across different versions of Python (platform independence) and exchanging data with other languages that support the same format (such as Java and C99). Another helpful tool is the sum() function which helps mitigate loss-of-precision during summation.
๐ŸŒ
Python
docs.python.org โ€บ 3 โ€บ library โ€บ decimal.html
decimal โ€” Decimal fixed-point and floating-point arithmetic
A: Yes, any binary floating-point number can be exactly expressed as a Decimal though an exact conversion may take more precision than intuition would suggest: >>> Decimal(math.pi) Decimal('3.141592653589793115997963468544185161590576171875') Q: Within a complex calculation, how can I make sure that I havenโ€™t gotten a spurious result because of insufficient precision or rounding anomalies.
๐ŸŒ
ZetCode
zetcode.com โ€บ python โ€บ decimal
Python Decimal - high-precision calculations in Python with Decimal
Neither of the types is perfect; generally, decimal types are better suited for financial and monetary calculations, while the double/float types for scientific calculations. The Decimal has a default precision of 28 places, while the float has 18 places. ... #!/usr/bin/python from decimal ...
๐ŸŒ
Mpmath
mpmath.org
mpmath - Python library for arbitrary-precision floating-point arithmetic
mpmath is a free (BSD licensed) Python library for real and complex floating-point arithmetic with arbitrary precision.
๐ŸŒ
AskPython
askpython.com โ€บ home โ€บ double precision floating values in python
Double precision floating values in Python - AskPython
April 10, 2025 - For tasks needing more precision, Python offers decimal. Decimal with configurable precision, fractions.Fraction for exact irreducible fractions, and numpy.float128 for up to 113 bits of precision.
๐ŸŒ
GeeksforGeeks
geeksforgeeks.org โ€บ precision-handling-python
Precision Handling in Python - GeeksforGeeks
August 9, 2024 - Python in its definition allows handling the precision of floating-point numbers in several ways using different functions. Most of them are defined under the "math" module. In this article, we will use high-precision calculations in Python with Decimal in Python.
Top answer
1 of 16
2330

You are running into the old problem with floating point numbers that not all numbers can be represented exactly. The command line is just showing you the full floating point form from memory.

With floating point representation, your rounded version is the same number. Since computers are binary, they store floating point numbers as an integer and then divide it by a power of two so 13.95 will be represented in a similar fashion to 125650429603636838/(2**53).

Double precision numbers have 53 bits (16 digits) of precision and regular floats have 24 bits (8 digits) of precision. The floating point type in Python uses double precision to store the values.

For example,

>>> 125650429603636838/(2**53)
13.949999999999999

>>> 234042163/(2**24)
13.949999988079071

>>> a = 13.946
>>> print(a)
13.946
>>> print("%.2f" % a)
13.95
>>> round(a,2)
13.949999999999999
>>> print("%.2f" % round(a, 2))
13.95
>>> print("{:.2f}".format(a))
13.95
>>> print("{:.2f}".format(round(a, 2)))
13.95
>>> print("{:.15f}".format(round(a, 2)))
13.949999999999999

If you are after only two decimal places (to display a currency value, for example), then you have a couple of better choices:

  1. Use integers and store values in cents, not dollars and then divide by 100 to convert to dollars.
  2. Or use a fixed point number like decimal.
2 of 16
838

There are new format specifications, String Format Specification Mini-Language:

You can do the same as:

"{:.2f}".format(13.949999999999999)

Note 1: the above returns a string. In order to get as float, simply wrap with float(...):

float("{:.2f}".format(13.949999999999999))

Note 2: wrapping with float() doesn't change anything:

>>> x = 13.949999999999999999
>>> x
13.95
>>> g = float("{:.2f}".format(x))
>>> g
13.95
>>> x == g
True
>>> h = round(x, 2)
>>> h
13.95
>>> x == h
True
Find elsewhere
Top answer
1 of 5
72

In the standard library, the decimal module may be what you're looking for. Also, I have found mpmath to be quite helpful. The documentation has many great examples as well (unfortunately my office computer does not have mpmath installed; otherwise I would verify a few examples and post them).

One caveat about the decimal module, though. The module contains several in-built functions for simple mathematical operations (e.g. sqrt), but the results from these functions may not always match the corresponding function in math or other modules at higher precisions (although they may be more accurate). For example,

from decimal import *
import math

getcontext().prec = 30
num = Decimal(1) / Decimal(7)

print("   math.sqrt: {0}".format(Decimal(math.sqrt(num))))
print("decimal.sqrt: {0}".format(num.sqrt()))

In Python 3.2.3, this outputs the first two lines

   math.sqrt: 0.37796447300922719758631274089566431939601898193359375
decimal.sqrt: 0.377964473009227227214516536234
actual value: 0.3779644730092272272145165362341800608157513118689214

which as stated, isn't exactly what you would expect, and you can see that the higher the precision, the less the results match. Note that the decimal module does have more accuracy in this example, since it more closely matches the actual value.

2 of 5
11

For this particular problem, decimal is a great way to go, because it stores the decimal digits as tuples!

>>> a = decimal.Decimal(9999999998)
>>> a.as_tuple()
DecimalTuple(sign=0, digits=(9, 9, 9, 9, 9, 9, 9, 9, 9, 8), exponent=0)

Since you're looking for a property that is most naturally expressed in decimal notation, it's a bit silly to use a binary representation. The wikipedia page you linked to didn't indicate how many "non-grafting digits" may appear before the "grafting digits" begin, so this lets you specify:

>>> def isGrafting(dec, max_offset=5):
...     dec_digits = dec.as_tuple().digits
...     sqrt_digits = dec.sqrt().as_tuple().digits
...     windows = [sqrt_digits[o:o + len(dec_digits)] for o in range(max_offset)]
...     return dec_digits in windows
... 
>>> isGrafting(decimal.Decimal(9999999998))
True
>>> isGrafting(decimal.Decimal(77))
True

I think there's a good chance the result of Decimal.sqrt() will be more accurate, at least for this, than the result of math.sqrt() because of the conversion between binary representation and decimal representation. Consider the following, for example:

>>> num = decimal.Decimal(1) / decimal.Decimal(7)
>>> decimal.Decimal(math.sqrt(num) ** 2) * 7
Decimal('0.9999999999999997501998194593')
>>> decimal.Decimal(num.sqrt() ** 2) * 7
Decimal('1.000000000000000000000000000')
๐ŸŒ
Luc
anh.cs.luc.edu โ€บ python โ€บ hands-on โ€บ 3.1 โ€บ handsonHtml โ€บ float.html
1.14. Decimals, Floats, and Floating Point Arithmetic โ€” Hands-on Python Tutorial for Python 3
Floating point numbers like 12.345 are a basic type, but there are some complications due to their inexactness. This section may be deferred until you actually need numbers other than integers. As you moved on in school from your first integer division to fractions and decimals, you probably thought of 6/8 as a fraction and could convert to a decimal .75. Python can do decimal calculations, too, approximately.
๐ŸŒ
The Floating-Point Guide
floating-point-gui.de โ€บ languages โ€บ python
The Floating-Point Guide - Floating-point cheat sheet for Python
Python has an arbitrary-precision decimal type named Decimal in the decimal module, which also allows to choose the rounding mode.
๐ŸŒ
Mpmath
mpmath.org โ€บ doc โ€บ current โ€บ technical.html
Precision and representation issues โ€” mpmath 1.3.0 documentation
On most systems, Pythonโ€™s float type represents an IEEE 754 double precision number, with a precision of 53 bits and rounding-to-nearest. With default precision (mp.prec = 53), the mpmath mpf type roughly emulates the behavior of the float type.
๐ŸŒ
Berkeley
pythonnumericalmethods.studentorg.berkeley.edu โ€บ notebooks โ€บ chapter09.02-Floating-Point-Numbers.html
Floating Point Numbers โ€” Python Numerical Methods
Instead of utilizing each bit as ... \(f\), which is the coefficient of the exponent. Almost all platforms map Python floats to the IEEE754 double precision - 64 total bits....
๐ŸŒ
LabEx
labex.io โ€บ tutorials โ€บ python-how-to-handle-python-float-precision-425669
How to handle Python float precision | LabEx
Learn effective techniques to manage floating-point precision challenges in Python, addressing common calculation errors and implementing robust numerical solutions for accurate computational results.
๐ŸŒ
Medium
medium.com โ€บ @goldengrisha โ€บ understanding-floating-point-precision-issues-in-python-a-practical-guide-5e17b2f14057
Understanding Floating-Point Precision Issues in Python: A Practical Guide | by Gregory Kovalchuk | Medium
September 25, 2024 - Letโ€™s consider a more complex scenario, one involving a physics simulation where we calculate forces. Suppose we have the following Python function to compute a force value `v(k, n)` and sum it over multiple iterations: def v(k: int, n: int) -> float: return 1 / (k * (n + 1) ** (2 * k)) def doubles(maxk: int, maxn: int) -> float: total = 0 old_total = 0 for k in range(1, maxk + 1): local_total = 0 for n in range(1, maxn + 1): local_total += v(k, n) old_total += v(k, n) # Updates old_total within the loop total += local_total return total
๐ŸŒ
Udacity
udacity.com โ€บ blog โ€บ 2025 โ€บ 03 โ€บ floating-point-numbers-in-python-what-they-are-and-how-to-use-them.html
Floating Point Numbers in Python: What They Are and How to Use Them | Udacity
March 10, 2025 - In this case, Decimal(โ€˜19.99โ€™) makes sure the value is stored precisely, avoiding binary floating-point errors. The quantize method lets us specify exactly how many decimal places we want, and ROUND_HALF_UP ensures consistent rounding behavior that matches what we expect in financial calculations.