To round a number to 2 decimal places in Python, use round(value, 2): round(1234.5678, 2) returns 1234.57. If you only need the number to look right on screen, format it instead with an f-string: f"{value:.2f}", or f"${value:,.2f}" for dollars. For money, use the decimal module so half-cents always round up. This guide shows each way to round to two decimal places, when to use which, and the float surprises that make round(2.675, 2) return 2.67.
Every example was run with Python 3.12.5, NumPy 2.5.3 and pandas 3.0.6 in the Windows Command Prompt, and the output shown is the real output. Reference: round(), format specification and decimal in the Python docs.
Round to 2 decimal places in Python
price = 1234.5678
print(round(price, 2)) # a number, rounded
print(f"{price:.2f}") # text, formatted for display
print(f"${price:,.2f}") # US currency style
Output:
1234.57
1234.57
$1,234.57
round() returns a number; the f-string returns text ready to display.| Goal | Use | Result for 1234.5678 |
|---|---|---|
| Round the value for more maths | round(x, 2) | 1234.57 (float) |
| Show 2 decimals on screen | f"{x:.2f}" | '1234.57' (string) |
| Show money | f"${x:,.2f}" | '$1,234.57' |
| Invoices and billing | Decimal(str(x)).quantize(...) | exact cents, half up |
The round() function
round() takes the number and how many decimal places you want. Without the second argument it returns an int, and a negative number rounds to tens, hundreds and so on:
total = 1234.5678
print(round(total, 2)) # 2 decimal places
print(round(total, 1)) # 1 decimal place
print(round(total)) # no second argument -> an int
print(type(round(total)).__name__)
print(round(total, -2)) # negative digits round to hundreds
Output:
1234.57
1234.6
1235
int
1200.0
Format a number to 2 decimal places (f-string, format, %)
Formatting keeps the original value and produces text. It also pads with zeros, so 5 becomes 5.00, which round() never does:
amount = 98765.4321
print(f"{amount:.2f}") # f-string (Python 3.6+)
print("{:.2f}".format(amount)) # str.format()
print("%.2f" % amount) # old printf style
print(f"{amount:,.2f}") # thousands separators
print(f"{amount:>12,.2f}") # right aligned in 12 characters
print(f"{0.19876:.2%}") # percentage with 2 decimals
Output:
98765.43
98765.43
98765.43
98,765.43
98,765.43
19.88%
round() vs formatting: which one do you need?
Use round() when the number goes into further calculations, and formatting when the number is about to be printed, written to a report or shown in a template:
price = 19.567
rounded = round(price, 2) # still a float
text = f"{price:.2f}" # now a string
print(rounded, type(rounded).__name__)
print(text, type(text).__name__)
print(rounded * 2) # maths works on the number
print(text * 2) # but "*" repeats the string instead
print(float(text) * 2) # convert back first
Output:
19.57 float
19.57 str
39.14
19.5719.57
39.14
Why round(2.675, 2) returns 2.67
This is the question behind most “Python rounding is broken” reports. Two different things are happening:
from decimal import Decimal
print(round(2.675, 2)) # expected 2.68
print(Decimal(2.675)) # why: 2.675 is not exactly 2.675 in binary
print([round(x) for x in (0.5, 1.5, 2.5, 3.5)]) # round half to even
print([round(x, 2) for x in (1.005, 2.665, 2.675, 0.125, 0.135)])
Output:
2.67
2.67499999999999982236431605997495353221893310546875
[0, 2, 2, 4]
[1.0, 2.67, 2.67, 0.12, 0.14]
- Binary floats: 2.675 cannot be stored exactly. Python keeps 2.674999999999999822…, which is below the halfway point, so it rounds down to 2.67.
- Round half to even: when a value really is exactly halfway, Python rounds to the nearest even digit, so
round(0.5)is 0 andround(2.5)is 2. This is the IEEE 754 default and it keeps large sums unbiased. - Both are correct behaviour, not bugs. When you need the school rule (0.005 always up), use
Decimal, as shown next.
Round money to 2 decimals with Decimal
For invoices, taxes and prices, use decimal and pass the value as a string. A float is already imprecise before Decimal ever sees it:
from decimal import Decimal, ROUND_HALF_UP
invoice = Decimal("2.675") # pass a STRING, not a float
print(invoice.quantize(Decimal("0.01"), rounding=ROUND_HALF_UP))
print(Decimal(2.675).quantize(Decimal("0.01"), rounding=ROUND_HALF_UP)) # float input: still 2.67
def to_cents(value):
"""Round a price the way an invoice does: 0.005 always goes up."""
return Decimal(str(value)).quantize(Decimal("0.01"), rounding=ROUND_HALF_UP)
for value in (2.675, 19.994, 5.005, 0.125):
print(f"{value:<8} -> {to_cents(value)}")
Output:
2.68
2.67
2.675 -> 2.68
19.994 -> 19.99
5.005 -> 5.01
0.125 -> 0.13
More on exact numbers in converting floats to integers in Python.
Round up or down to 2 decimal places
round() goes to the nearest value. To force the direction, use math.ceil() and math.floor() with a factor of 100, or Decimal with an explicit rounding mode:
import math
from decimal import Decimal, ROUND_CEILING, ROUND_FLOOR
shipping = 12.341
print(math.ceil(shipping * 100) / 100) # always up
print(math.floor(shipping * 100) / 100) # always down (truncate)
print(Decimal("12.341").quantize(Decimal("0.01"), rounding=ROUND_CEILING))
print(Decimal("12.349").quantize(Decimal("0.01"), rounding=ROUND_FLOOR))
print(int(shipping * 100) / 100) # int() also truncates
Output:
12.35
12.34
12.35
12.34
12.34
Round a NumPy array or pandas DataFrame
Both libraries round whole columns at once. Note that NumPy does the scaling differently, so np.round(2.675, 2) gives 2.68 where the built-in round() gives 2.67:
import numpy as np
import pandas as pd
prices = np.array([2.675, 19.994, 5.005, 12.3456])
print(np.round(prices, 2)) # NumPy: note 2.675 -> 2.68
print(round(2.675, 2), "<- built-in round() gives 2.67")
df = pd.DataFrame({"price": [19.994, 5.005, 12.3456], "qty": [3, 2, 1]})
df["total"] = (df["price"] * df["qty"]).round(2)
print(df.round(2).to_string(index=False))
print(df["total"].map(lambda v: f"${v:,.2f}").tolist()) # display as money
Output:
[ 2.68 19.99 5. 12.35]
2.67 <- built-in round() gives 2.67
price qty total
19.99 3 59.98
5.00 2 10.01
12.35 1 12.35
['$59.98', '$10.01', '$12.35']
DataFrame.round(2) rounds every numeric column; formatting turns them into dollars.Related: convert floats to integers in pandas and change the data type of a column.
Mistakes to avoid
values = [0.005, 0.005, 0.005, 0.005]
print(sum(values)) # 0.02
print(round(sum(values), 2)) # round once at the end
print(sum(round(v, 2) for v in values)) # rounding first changes the total
try:
round("3.14159", 2) # round() needs a number
except TypeError as e:
print("TypeError:", e)
print(round(float("3.14159"), 2))
print(0.1 + 0.2, "->", round(0.1 + 0.2, 2))
Output:
0.02
0.02
0.04
TypeError: type str doesn't define __round__ method
3.14
0.30000000000000004 -> 0.3
- Round once, at the end. In the example, four values of 0.005 add up to 0.02, but rounding each one first turns the total into 0.04 — rounding early changes the answer.
round()needs a number.round("3.14159", 2)raisesTypeError; convert withfloat()first.- Do not store money as floats in accounting code. Use
Decimal(or whole cents as integers) and format only when displaying. - Formatting does not change the value:
f"{x:.2f}"is text, so convert it back withfloat()if you need to calculate with it.
More Python number tutorials:
- Convert a string to an integer in Python
- Convert a float to an int
- Pad numbers with leading zeros
- Remove trailing zeros from a decimal
Frequently asked questions
How do I round to 2 decimal places in Python?
Use round(value, 2). For display only, use an f-string: f"{value:.2f}".
Why does round(2.675, 2) give 2.67 instead of 2.68?
2.675 cannot be stored exactly in binary; Python holds 2.67499999999999982…, which rounds down. Use Decimal("2.675").quantize(Decimal("0.01"), rounding=ROUND_HALF_UP) to get 2.68.
What is the difference between round() and an f-string?
round() returns a number you can keep calculating with; the f-string returns a string for display and always shows two decimals, including trailing zeros.
How do I always round up to 2 decimals?
math.ceil(value * 100) / 100, or Decimal(str(value)).quantize(Decimal("0.01"), rounding=ROUND_CEILING).
How do I show 2 decimal places with a dollar sign and commas?
f"${value:,.2f}" gives $1,234.57.
How do I round a pandas column to 2 decimals?
df["price"] = df["price"].round(2), or df.round(2) for every numeric column.
Bijay Kumar is a 13-time Microsoft MVP with more than 18 years in software development, and the founder of Python Guides and TSinfo Technologies. He started out building .NET and SharePoint solutions at HP, TCS and KPIT before moving into Python, machine learning and AI, and he also builds web apps with TypeScript and React. He writes the tutorials here himself, and every example is run before publishing so you see the real output. More about Bijay · Microsoft MVP profile · LinkedIn