Every Python program that handles prices, measurements, sensor readings, or scientific data needs decimal numbers. Python calls them floats, and writing them is straightforward once you know the rules. This tutorial walks you through every way to create and work with decimal numbers in Python, starting from the simplest float literal and building up to the decimal module for precision-critical work.
If you have ever typed a number like 9.99 or 0.5 into a Python file, you have already created a float. The decimal point is the signal that tells Python to treat the number as a floating-point value rather than an integer. But there is more to the story than just adding a dot. Python gives you multiple ways to write decimal numbers, each suited to different situations, and understanding them all makes your code cleaner and more intentional.
What Is a Float in Python?
A float (short for floating-point number) is Python's primary type for representing numbers that have a fractional component. When you write 42, Python creates an int. When you write 42.0, Python creates a float. The decimal point is what separates the two types.
whole_number = 42
decimal_number = 42.0
print(type(whole_number)) # <class 'int'>
print(type(decimal_number)) # <class 'float'>
Under the hood, Python stores floats using the IEEE 754 double-precision format, which gives you roughly 15 to 17 significant digits of precision. This is the same standard used by C, Java, JavaScript, and virtually every other mainstream language. It means Python floats occupy 64 bits of memory regardless of the number's size.
You can always check whether a value is a float by calling type() on it or by using isinstance(value, float). Both approaches tell you unambiguously what type you are working with.
Python also has a built-in float() function that converts other types into floats, and a decimal module in the standard library for situations where the default float precision is not sufficient. We will cover both of these later in this tutorial.
Build a valid Python statement that creates a float variable named price with the value 19.99:
Four Ways to Write Decimal Numbers
Python offers several syntactic forms for expressing decimal values. Each one produces a float, but they serve different readability and convenience goals.
1. Standard Float Literals
The simplest and most common approach is to type the number with a decimal point. You can include digits on both sides of the point, or you can omit digits from one side. All three of the following lines create a valid float:
full_form = 3.14 # both sides of the decimal point
short_left = .5 # no digit before the point (same as 0.5)
short_right = 5. # no digit after the point (same as 5.0)
print(full_form) # 3.14
print(short_left) # 0.5
print(short_right) # 5.0
While .5 and 5. are both legal Python, writing 0.5 and 5.0 is considered better style. The explicit leading or trailing zero makes your intent clearer to anyone reading the code.
2. Scientific (Exponential) Notation
When you need to express very large or very small numbers, scientific notation keeps your code readable. The letter e (or E) separates the base number from the power of 10:
speed_of_light = 3e8 # 300,000,000.0
electron_mass = 9.109e-31 # 0.0000000000000000000000000000009109
print(speed_of_light) # 300000000.0
print(electron_mass) # 9.109e-31
The number after e tells Python how many positions to shift the decimal point. A positive exponent shifts it to the right (making the number larger), and a negative exponent shifts it to the left (making it smaller). The result is always a float, even if the final value is a whole number like 3e8.
3. Underscores for Readability
Since Python 3.6, you can insert underscores between digits in any numeric literal. The underscores are purely visual separators and have no effect on the stored value:
budget = 1_500_000.75
pi = 3.141_592_653
print(budget) # 1500000.75
print(pi) # 3.141592653
This feature was introduced by PEP 515 and works the same way for integers, floats, and even hexadecimal or binary literals. The only rule is that underscores must appear between digits -- not at the start, end, or directly next to the decimal point.
4. The float() Constructor
The built-in float() function converts integers, strings, and other compatible types into floats:
from_int = float(42) # 42.0
from_string = float("3.14") # 3.14
from_sci = float("2.5e-3") # 0.0025
no_args = float() # 0.0
# Special values
positive_inf = float("inf") # inf
negative_inf = float("-inf") # -inf
not_a_number = float("nan") # nan
The float() function is essential when you need to convert user input (which Python reads as a string) or data from a file into a numeric value you can do math with. It also provides the only way to create the special float values inf, -inf, and nan, which have no literal syntax in Python.
- When to use
- Everyday decimal values like prices, measurements, and coordinates.
- Python version
- All versions
- When to use
- Very large numbers (distances, speeds) or very small numbers (particle masses, tolerances).
- Python version
- All versions
- When to use
- Long numbers where visual grouping improves clarity, such as budgets or population figures.
- Python version
- Python 3.6+
- When to use
- Converting strings (user input, file data, API responses) and creating special values like inf or nan.
- Python version
- All versions
This code tries to convert user input to a float and calculate a total. One line has a bug. Find it.
int(user_input) to float(user_input). The string "24.99" contains a decimal point, so int() raises a ValueError. You must use float() to convert strings that contain decimal values.
Why Floats Are Not Perfectly Precise
One of the things that surprises beginners about Python floats is that they cannot represent every decimal value exactly. Try this in a Python shell:
print(0.1 + 0.2) # 0.30000000000000004
print(0.1 + 0.2 == 0.3) # False
This is not a Python bug. It happens because the computer stores floats as binary (base-2) fractions. The value 0.1 does not have an exact binary representation, just as the fraction 1/3 does not have an exact decimal representation (0.333... repeats forever). The computer stores the closest possible approximation, and when you combine multiple approximations, the tiny errors can become visible.
Never compare floats for exact equality with == when the values come from arithmetic. Use round() to compare rounded values, or use math.isclose(a, b) to check whether two floats are within an acceptable tolerance of each other.
For general-purpose math, the slight imprecision of floats is harmless. But for financial calculations, accounting ledgers, or anywhere you need numbers to match exactly, Python provides the decimal module (covered in the next section) and the fractions module for rational arithmetic.
How to Write Decimal Numbers in Python Code
Follow these five steps to confidently create and use decimal numbers in any Python program. Each step builds on the one before it.
-
Write a float literal with a decimal point
Type a number with a period to create a float. For example,
price = 9.99stores a float value. The decimal point is what tells Python this is a float rather than an int. Always include a digit on both sides of the point for clarity: write0.5instead of.5. -
Use scientific notation for very large or small numbers
Add
eorEfollowed by the power of 10. For example,distance = 1.496e11represents 149,600,000,000.0 (the Earth-to-Sun distance in meters). Use a negative exponent for small numbers:charge = 1.6e-19. -
Add underscores for readability
Place underscores between digits to visually group thousands:
budget = 1_500_000.75. Python ignores the underscores entirely. This works in Python 3.6 and later, and applies to integers, floats, and even hex or binary literals. -
Convert other types to float with float()
Use the built-in
float()function to convert integers or strings:float(42)returns42.0andfloat('3.14')returns3.14. This is essential when reading user input withinput(), since Python always returns a string from that function. -
Use the decimal module when precision matters
Import the
Decimaltype withfrom decimal import Decimaland initialize it with strings:Decimal('0.10'). UseDecimalfor financial calculations, tax computations, or anywhere exact base-10 arithmetic is required. Avoid passing floats to the Decimal constructor, as that imports the float's existing imprecision.
The decimal Module: When Precision Matters
Python's standard library includes the decimal module, which provides the Decimal type for exact base-10 arithmetic. Unlike the built-in float, Decimal stores numbers exactly as you write them, preserving trailing zeros and avoiding binary rounding errors.
from decimal import Decimal
# Always initialize with strings to preserve precision
a = Decimal("0.1")
b = Decimal("0.2")
print(a + b) # 0.3
print(a + b == Decimal("0.3")) # True
# Trailing zeros are preserved
total = Decimal("1.20") + Decimal("1.30")
print(total) # 2.50
Notice that Decimal("1.20") + Decimal("1.30") produces 2.50, not 2.5. The Decimal type preserves the significance of the trailing zero, which matters in financial reporting and scientific measurement.
One important rule: always pass strings to the Decimal constructor, not floats. Writing Decimal(0.1) first creates a float approximation of 0.1 and then converts that imprecise value into a Decimal, carrying the rounding error along with it. Writing Decimal("0.1") avoids this entirely.
from decimal import Decimal
# Do this:
correct = Decimal("0.1")
print(correct) # 0.1
# Not this:
wrong = Decimal(0.1)
print(wrong) # 0.1000000000000000055511151231257827021181583404541015625
"Computers must provide an arithmetic that works in the same way as the arithmetic that people learn at school." — General Decimal Arithmetic Specification
Python Learning Summary Points
- The decimal point creates a float. Writing
42.0instead of42changes the type frominttofloat. Python treats these as fundamentally different types, even when the numeric value appears identical. - Python offers four ways to express float values. Standard literals (
3.14), scientific notation (3e8), underscore-separated literals (1_000.50), and thefloat()constructor all produce the samefloattype but serve different readability goals. - Floats are approximations. Because Python stores floats in binary (IEEE 754), values like 0.1 cannot be represented exactly. Use
math.isclose()for comparisons and thedecimalmodule for precision-critical work like financial calculations. - Initialize Decimal with strings. Always write
Decimal("0.10"), neverDecimal(0.10). The string form preserves exact base-10 precision and avoids inheriting the rounding error that already exists in the float. - Round and format deliberately. Use
round(value, n)for numeric rounding and f-strings likef"{value:.2f}"for display formatting. These tools give you full control over how your decimal numbers appear to users.
Decimal numbers are one of the building blocks you will use in almost every Python program. Now that you know how to write them, convert them, and handle their precision limits, you have a solid foundation to work with prices, measurements, scientific data, and any other values that need a fractional component.
Frequently Asked Questions
An int stores whole numbers without a decimal point, like 7 or -42. A float stores numbers with a decimal component, like 7.0 or -42.5. Python treats these as two distinct types. Writing 7 creates an int, while writing 7.0 creates a float.
Place a decimal point (period character) in the number. For example, 3.14 and 0.5 are both valid float literals. You can also write .5 without the leading zero, or 5. with nothing after the point. Both forms create a float value.
The letter e (or E) indicates scientific notation. The number after e tells Python how many places to shift the decimal point. 2.5e3 means 2.5 multiplied by 10 to the power of 3, which equals 2500.0. A negative exponent like 2.5e-3 shifts the decimal left, producing 0.0025.
Python stores floats as binary (base-2) fractions. The value 0.1 cannot be represented exactly in binary, so the computer stores a very close approximation. When you add two approximations together, the tiny rounding errors compound. The result 0.30000000000000004 is correct behavior for binary floating-point math, not a bug.
Yes. Since Python 3.6, you can place underscores between digits in any numeric literal for readability. For example, 1_000_000.50 is the same as 1000000.50. Underscores are ignored by the interpreter and have no effect on the value.
The decimal module provides the Decimal type, which stores numbers as base-10 values instead of base-2 approximations. This means Decimal('0.1') + Decimal('0.2') equals exactly Decimal('0.3'). It is the preferred choice for financial calculations, accounting, and anywhere exact decimal precision matters.
Use the built-in float() function. Pass the string as an argument: float('3.14') returns the float value 3.14. The string must contain a valid numeric format. Passing a non-numeric string like float('hello') raises a ValueError.
Use the built-in round() function with two arguments: the number and the number of decimal places. For example, round(3.14159, 2) returns 3.14. For formatted string output, use an f-string like f'{value:.2f}' which produces a string representation with exactly two decimal places.
The largest finite float is approximately 1.8 times 10 to the 308th power. You can find this limit with sys.float_info.max. Numbers beyond this range are represented as inf (infinity). The smallest positive float (closest to zero) is approximately 5e-324.
Use Decimal for money. The float type introduces tiny rounding errors because it stores values in binary. The Decimal type stores values in base-10, which matches how currencies work. Initialize Decimal with strings like Decimal('19.99') to avoid inheriting float precision problems from the start.