Python floats are the language's built-in type for numbers with fractional parts, and they are implemented using the IEEE 754 double-precision binary floating-point standard that your computer's processor supports directly in hardware. This means float arithmetic is fast, but it also means that floats inherit a fundamental limitation of binary floating-point representation: many decimal fractions that look simple to a human, like 0.1 or 0.3, cannot be stored exactly in binary, just as 1/3 cannot be written exactly in decimal. Understanding this limitation and how to work with it is essential before you use floats for anything where exact values matter.
If you have read the articles on Python data types and the integer data type, you already know that integers handle whole numbers with unlimited precision. Floats handle the rest of the number line, from tiny scientific quantities to astronomical distances, but they do so with a fixed precision of approximately 15 to 17 significant decimal digits.
Creating floats and the representation surprise
Any number with a decimal point or an exponent is a float in Python. Writing 3.14, -0.001, or 2.0 all produce float objects. You can also use scientific notation with an e or E to indicate powers of ten: 1.5e-3 means 1.5 times 10 to the power of negative 3, which is 0.0015. The float constructor converts other types when the conversion is meaningful. Passing an integer returns the equivalent float, and passing a string parses it into a float value.
The most famous surprise in floating-point arithmetic occurs when you add two seemingly simple decimals:
print(0.1 + 0.2) # 0.30000000000000004
print(0.1 + 0.2 == 0.3) # FalseThe numbers 0.1 and 0.2 cannot be represented exactly in binary, so each is stored as the closest binary approximation. Their sum is also an approximation, and it differs slightly from the binary approximation of 0.3. The difference is about 5.55 times 10 to the power of negative 17, which is invisibly small in most printed output but causes exact equality comparisons to fail. This is not a Python bug; it is a consequence of how all IEEE 754 floating-point hardware works, and every language that uses hardware floats has the same behavior.
Comparing floats safely
Because exact equality comparisons are unreliable with floats, Python's math module provides the isclose function for comparing floats with a tolerance. You specify a relative tolerance, an absolute tolerance, or both, and the function returns True if the values are within that tolerance of each other. The relative tolerance defaults to 1e-9, which is appropriate for most everyday calculations.
For display purposes, f-string formatting is the right tool. Writing f"{value:.2f}" rounds the value to two decimal places for display without changing the underlying float object. This is the correct approach for presenting currency, percentages, or measurements to users. The built-in round function also rounds floats, but it uses banker's rounding where halfway cases round to the nearest even number. This means round(2.5) returns 2 rather than 3, which avoids upward bias when rounding large datasets but surprises beginners who expect standard rounding.
Special float values
IEEE 754 defines several special float values that Python surfaces directly. Positive and negative infinity represent values that exceed the maximum representable float, and they behave as expected in comparisons and arithmetic. Dividing a positive number by zero produces positive infinity. NaN, which stands for Not a Number, represents the result of an undefined operation like zero divided by zero. NaN has the unusual property that it is not equal to itself, so comparing NaN to NaN returns False. To check for NaN, use the math.isnan function rather than an equality comparison:
import math
print(float('inf') > 999999) # True
print(math.isnan(float('nan'))) # TrueWhen to use Decimal instead of float
The decimal module provides a Decimal type that stores numbers in base-10 rather than binary, which means it can represent decimal fractions like 0.1 exactly. Decimal arithmetic is slower than float arithmetic because it is implemented in software rather than hardware, but for financial calculations, invoice totals, or any scenario where 0.1 plus 0.2 must equal exactly 0.3, Decimal is the correct choice.
The rule of thumb is straightforward: use float for scientific measurements, graphics coordinates, statistics, and machine learning where a tiny representation error is acceptable. Use Decimal for money, accounting, and any domain where decimal fractions must add up to exact values. Python gives you both tools and trusts you to choose the right one for the task. The next article on the boolean data type covers a simpler type with only two possible values, but one that is equally fundamental to how Python programs make decisions.
Rune AI
Key Insights
- Python floats use IEEE 754 double precision (64-bit) with about 15-17 significant digits.
- Decimal fractions like 0.1 cannot be represented exactly in binary floating-point.
- Compare floats with math.isclose(), not ==, when tolerance matters.
- round() uses banker's rounding; format strings like f'{x:.2f}' round for display.
- Use the Decimal module for exact decimal arithmetic in financial applications.
- Scientific notation like 1.5e-3 is valid Python syntax for float literals.
Frequently Asked Questions
Why does 0.1 + 0.2 not equal 0.3 in Python?
How do I round a float to a specific number of decimal places?
What is the difference between float and Decimal in Python?
Conclusion
Python floats give you fast, hardware-accelerated arithmetic for real numbers, at the cost of small representation errors for decimal fractions. Understanding where these errors come from and how to work around them with rounding, tolerance comparisons, and the Decimal module separates confident Python programmers from beginners who get surprised by 0.1 + 0.2.
More in this topic
Create and Assign Variables in Python
Learn every way to create and assign variables in Python, from basic single assignment to expressions, type hints, and practical patterns beginners use every day.
Python Variable Naming Rules
Learn Python's variable naming rules, including allowed characters, reserved keywords, PEP 8 conventions, and how to choose names that make your code readable.
Python Variables Explained
Understand what Python variables are, how they store and reference data, and why Python's variable model is different from other programming languages.