Kodeclik Blog
How to round to two decimal places in Python
You will often need to round numbers to two decimal places. For instance, two decimal places are essential when dealing with currency and monetary values, as most currencies use cents or similar subdivisions that represent 1/100 of the main unit. For example, in the UK, financial values should be limited to two decimal places to match the penny (£0.01) as the lowest unit of legal tender. In the US we wish to write amounts in dollars and cents, and 100 cents make up a dollar, again necessitating two decimal digits.
Here are three common methods to display numbers with two decimal places in Python, and one “back to basics” method.
Method 1: Use the round() Function
The round() function is the simplest way to handle decimal places in Python. It takes two arguments: the number to round and the number of decimal places desired. The function returns a float rounded to the specified number of decimal places.
Here’s a simple program to explore:
number = 3.14159
rounded_number = round(number, 2)
print(rounded_number) # Output: 3.14
Method 2: Use String Formatting
Here, we are not really modifying the number but simply exerting control over how it is printed.
number = 3.14159
formatted_number = "{:.2f}".format(number)
print(formatted_number) # Output: 3.14
String formatting provides precise control over how numbers are displayed. The format specifier ".2f" indicates that we want two decimal places, where .2 specifies the precision and f indicates we're formatting a float.
Method 3: Use F-strings
This is a variant of Method 2 above as F-strings provide a more modern and readable approach to string formatting in Python.
number = 3.14159
formatted_number = f"{number:.2f}"
print(formatted_number) # Output: 3.14
As you can see, the syntax is similar to the format() method, but it's more concise and allows for direct embedding of expressions inside the string. The :.2f specification works the same way as in the format() method, where .2 indicates two decimal places and f specifies a float format.
Method 4: “Back to Basics”
Here is a back to basics approach that does not use any of the above approaches but instead works to systematically look for the digit beyond the decimal point and starts organizing them into an answer:
import math
def progressive_decimal(number, decimal_places):
# Multiply by 10^decimal_places to shift decimal point right
shifted = number * (10 ** decimal_places)
# Floor the number to remove extra decimals
floored = math.floor(shifted)
# Divide back by same factor to get original decimal position
result = floored / (10 ** decimal_places)
return result
# Example usage
number = 123.456
result = progressive_decimal(number, 2)
print(result) # Output: 123.45
The function above (progressive_decimal) works by first multiplying the number by 10 raised to the power of the desired decimal places, which shifts the decimal point right. Then it uses math.floor() to truncate any remaining decimal places. Finally, it divides by the same factor to shift the decimal point back to the correct position. For the input 123.456 with 2 decimal places, it correctly returns 123.45.
While it is fun to write our own function, it is perhaps a better idea to go with Python's built-in round() function.
Our custom progressive_decimal() function uses multiplication and floor division to achieve rounding, while round() uses a more sophisticated "round half to even" (banker's rounding) algorithm. Due to this, the built-in round() function handles edge cases better, particularly with floating-point precision. For numbers exactly halfway between two values, round() uses banker's rounding to reduce bias by rounding to the nearest even number. Our custom function doesn't implement this behavior.
Also, the built-in round() function is implemented in C, making it significantly faster than our custom Python implementation which requires multiple arithmetic operations.
The built-in round() function also handles negative decimal places and can round to powers of 10, while our custom implementation doesn't account for these cases. For example:
# Built-in round can handle negative digits
print(round(3.14159, -1)) # Rounds to nearest 10
This will return a value of 0. Given these differences, the built-in round() function is generally the better choice unless there's a specific need for the custom implementation's behavior.
Enjoy this blogpost? Want to learn Python with us? Sign up for 1:1 or small group classes.