Question
In Python, I want a value like a to be rounded to 13.95. I tried using round(), but I still see this result:
>>> a
13.949999999999999
>>> round(a, 2)
13.949999999999999
Why does this happen, and how can I correctly limit a float to two decimal places when displaying or working with the value?
Short Answer
By the end of this page, you will understand why Python floats sometimes display long imprecise values, why round() may not appear to fix the issue, and when to use formatting versus Decimal for exact two-decimal-place results.
Concept
Python's float type stores numbers in binary floating-point, not exact decimal form. Many decimal values that look simple to humans cannot be represented exactly in binary.
That means a number that should look like 13.95 may actually be stored internally as something very close to it, such as:
13.949999999999999
This is not usually a Python bug. It is a normal property of binary floating-point arithmetic used by many programming languages.
round(a, 2) rounds the numeric value, but the internal float may still not have an exact decimal representation. Depending on how the value is displayed, you may still see the longer form.
There are two important ideas here:
- Rounding a number changes its numeric value.
- Formatting a number changes how it is displayed.
If your goal is just to show 13.95 to a user, formatting is usually the right tool.
If your goal is to perform exact decimal arithmetic, such as with money, float is often the wrong tool. In those cases, use Python's decimal.Decimal type instead.
This matters in real programming because prices, totals, tax calculations, reports, and user interfaces often require values to appear with a fixed number of decimal places.
Mental Model
Think of a float like a measuring tape marked in a system that does not perfectly match decimal numbers.
You ask for 13.95, but the tape can only mark the closest possible binary value, not the exact decimal one. So Python stores the nearest available value.
Then:
round()says, "Use the nearest value at 2 decimal places."- formatting says, "Show this value to the user with 2 decimal places."
So even if the stored number is slightly off internally, formatting can still display exactly:
13.95
For money, imagine using a cash register that must track cents exactly. In that case, you would not want an approximate tape measure. You would want an exact decimal system like Decimal.
Syntax and Examples
The most common ways to work with two decimal places in Python are:
1. Format for display
a = 13.949999999999999
print(f"{a:.2f}")
Output:
13.95
:.2f means:
f= fixed-point notation.2= show 2 digits after the decimal point
This is the best choice when displaying numbers in the terminal, UI, logs, or reports.
2. Use round() for numeric rounding
a = 13.949999999999999
b = round(a, 2)
print(b)
Possible output:
13.95
In many cases this works as expected, but remember: the result is still a float, so it may still be an approximation internally.
3. Use for exact decimal arithmetic
Step by Step Execution
Consider this example:
a = 13.949999999999999
b = round(a, 2)
text = f"{a:.2f}"
print(a)
print(b)
print(text)
Step by step:
-
a = 13.949999999999999- Python stores this as a
float. - Internally, it uses binary floating-point.
- Python stores this as a
-
b = round(a, 2)- Python rounds
ato 2 decimal places. - The result is still a
float. - It is numerically close to
13.95, but may still not be exact internally.
- Python rounds
-
text = f"{a:.2f}"- Python converts the number into a string.
- The string is formatted to exactly 2 digits after the decimal point.
textis now'13.95'.
Real World Use Cases
Showing prices in an app
price = 13.949999999999999
print(f"${price:.2f}")
You want users to see $13.95, not a long floating-point value.
Generating reports
When exporting sales or analytics reports, values are often displayed with 2 decimal places for readability.
API responses
If an API returns numeric summaries, developers often format values before presenting them in dashboards or client apps.
Scientific and measurement output
Sometimes exact decimal storage is not required, but readable output is. Formatting makes the result easier to interpret.
Financial calculations
If you are calculating invoices, totals, taxes, or balances, use Decimal instead of float to avoid precision issues accumulating over time.
Real Codebase Usage
In real projects, developers usually choose one of these patterns:
1. Keep floats internally, format at the edges
This is common when exact decimal precision is not critical.
def format_score(score: float) -> str:
return f"{score:.2f}"
The app keeps numeric values for calculations, then formats them only when displaying them.
2. Use Decimal for money
from decimal import Decimal
def calculate_total(price: Decimal, tax: Decimal) -> Decimal:
return price + tax
This avoids float precision problems in accounting-style logic.
3. Validate and normalize input early
def normalize_price(value):
return round(float(value), 2)
This can be useful when accepting user input, but for money, converting directly to from strings is safer.
Common Mistakes
Mistake 1: Expecting float to store decimal values exactly
Broken expectation:
a = 13.95
print(a)
You may expect exact decimal storage, but floats are approximate.
Avoid this by remembering:
floatis usually fine for many calculationsDecimalis better for exact decimal arithmetic
Mistake 2: Using round() when you really want formatting
a = 13.949999999999999
print(round(a, 2))
If your goal is display, prefer:
print(f"{a:.2f}")
Mistake 3: Assuming formatted output is still numeric
Broken code:
price = 13.949999999999999
price = f"{price:.2f}"
result = price +
Comparisons
| Approach | Returns | Best for | Exact decimal? | Example |
|---|---|---|---|---|
round(a, 2) | float | Numeric rounding | No | round(13.949999999999999, 2) |
f"{a:.2f}" | str | Displaying 2 decimal places | Display only | f"{a:.2f}" |
format(a, ".2f") | str | Display formatting | Display only |
Cheat Sheet
Quick reference
Round a float
round(value, 2)
- Returns a
float - Useful for numeric rounding
- Still may not be exact internally
Format to 2 decimal places
f"{value:.2f}"
format(value, ".2f")
- Returns a
str - Best for display
- Always shows 2 digits after the decimal point
Use exact decimal arithmetic
from decimal import Decimal
amount = Decimal("13.95")
- Best for money
- Create from strings, not floats
Important rule
- Need a number? Use
round()orDecimal - Need display text? Use formatting
Common edge case
FAQ
Why does Python show 13.949999999999999 instead of 13.95?
Because float uses binary floating-point, and many decimal numbers cannot be represented exactly in that format.
Why doesn't round(a, 2) always seem to fix it?
round() returns a rounded float, but float values are still stored approximately. For display, use formatting.
How do I always show two decimal places in Python?
Use string formatting:
f"{value:.2f}"
Should I use float for money?
Usually no. Use decimal.Decimal for currency and other exact decimal calculations.
What is the difference between round() and :.2f?
round() returns a number. :.2f returns a formatted string.
Mini Project
Description
Build a small receipt formatter in Python that demonstrates the difference between storing numeric values, rounding them, and formatting them for display. This mirrors real applications such as checkout systems, invoices, and order summaries.
Goal
Create a program that prints item prices, a subtotal, tax, and a final total with exactly two decimal places.
Requirements
- Store at least three item prices in a list.
- Calculate the subtotal and tax.
- Display all money values with exactly two decimal places.
- Include one version using
floatformatting. - Include one version using
Decimalfor safer money handling.
Keep learning
Related questions
@staticmethod vs @classmethod in Python Explained
Learn the difference between @staticmethod and @classmethod in Python with clear examples, use cases, mistakes, and a mini project.
Call a Function by Name in a Python Module
Learn how to call a function by name in a Python module using strings, getattr, and safe patterns for dynamic function dispatch.
Catch Multiple Exceptions in One except Block in Python
Learn how to catch multiple exceptions in one Python except block using tuples, with examples, mistakes, and real-world usage.