DEV Community

Cover image for Floating-Point Precision in Programming
Dilan
Dilan

Posted on • Edited on

7 2 3 2 4

Floating-Point Precision in Programming

If you’ve ever encountered a situation where simple arithmetic in Python doesn’t give the result you expect, you’re not alone. This is a common issue involving floating-point precision. But don’t worry — it’s not an error, just a quirk of how computers handle numbers.

In this article, we’ll explore:

  • What floating-point numbers are
  • Why they sometimes behave unexpectedly
  • Real-world examples
  • Solutions for dealing with floating-point precision in Python

What Are Floating-Point Numbers?

A floating-point number is simply a number that can have a fractional part (a decimal). Unlike whole numbers (integers), floating-point numbers let you work with values like 0.5, 3.14, or 0.0001.

But there’s a catch: computers store these numbers in a binary format (ones and zeros). And, just like how you can’t write some fractions in decimal (e.g., 1/3 becomes 0.333...), certain decimal numbers can't be stored exactly in binary form.

Why Does Floating-Point Precision Go Wrong?

The problem arises because computers use a system called IEEE 754 to represent floating-point numbers in binary. Unfortunately, not every decimal value can be stored accurately. Numbers like 0.1, 0.2, and 0.3 are just approximations when converted to binary.

For example:

  • The binary version of 0.2 is actually something like 0.0011001100110011... (it keeps repeating forever).
  • Because the computer can’t store an infinite number of digits, it rounds off this value.

This rounding leads to tiny inaccuracies, which add up when you do arithmetic with these numbers.

A Simple Example of Floating-Point Precision Problems

Let’s see this in action with a simple example:

a = 0.2 + 0.4
b = 0.6

print(a == b)  # Output: False
Enter fullscreen mode Exit fullscreen mode

At first glance, you might think 0.2 + 0.4 should equal 0.6, but Python says it doesn’t. Why? The sum of 0.2 + 0.4 is stored as 0.6000000000000001 due to the way 0.2 and 0.4 are approximated in binary.

Here’s another example:

a = 0.1 + 0.3
b = 0.4

print(a == b)  # Output: True
Enter fullscreen mode Exit fullscreen mode

This time, the result is True. It seems inconsistent, right? But in this case, the approximation of 0.1 + 0.3 is close enough to 0.4 that Python considers them equal.

Why Does This Happen?

Let’s break it down a bit more. When you write 0.2 in Python, it’s stored as a repeating binary fraction:

0.2 ≈ 0.001100110011...
Enter fullscreen mode Exit fullscreen mode

Since the computer can’t store an infinite sequence, it cuts off the number at a certain point, which causes rounding errors. When you add 0.2 and 0.4, these small errors can add up, leading to a value like 0.6000000000000001.

How to Handle Floating-Point Precision in Python

Now that we know why this happens, how can we handle it? Luckily, there are several ways to deal with floating-point precision issues in Python.

1. Use math.isclose() for Comparisons

Instead of comparing floating-point numbers with ==, you can use Python’s math.isclose() function. This checks if two numbers are approximately equal, allowing for a tiny error margin.

import math

a = 0.2 + 0.4
b = 0.6

print(math.isclose(a, b))  # Output: True
Enter fullscreen mode Exit fullscreen mode

By allowing for a small difference, math.isclose() helps avoid problems caused by rounding errors.

2. Rounding Numbers

Another simple way to handle floating-point precision is by rounding the numbers before comparing them.

a = round(0.2 + 0.4, 2)
b = round(0.6, 2)

print(a == b)  # Output: True
Enter fullscreen mode Exit fullscreen mode

In this example, we round the numbers to 2 decimal places, ensuring that 0.6000000000000001 becomes exactly 0.6.

3. Use the decimal Module for Higher Precision

If you need even more precision, Python has a built-in decimal module. This module allows you to work with decimal numbers more accurately than floating-point numbers.

from decimal import Decimal

a = Decimal('0.2') + Decimal('0.4')
b = Decimal('0.6')

print(a == b)  # Output: True
Enter fullscreen mode Exit fullscreen mode

With decimal.Decimal, the numbers are stored exactly as you write them, so 0.2 is truly 0.2—no approximations!

4. Avoid Floating-Point Arithmetic

In some cases, like financial calculations, it’s best to avoid floating-point arithmetic altogether. Instead, work with integers (for example, handling cents instead of dollars). This ensures that you don’t encounter any precision issues.

Why Floating-Point Issues Are Normal

It’s important to remember that these issues are not Python-specific. They occur in virtually all programming languages, such as Java, C++, and JavaScript. These languages all use the same IEEE 754 standard to store floating-point numbers, so they all face the same limitations.

While it might seem like a bug, it’s just the way computers work. Luckily, now that you understand the issue, you can handle it with the tools we discussed.

Conclusion

Floating-point precision issues are a common challenge when working with numbers that have decimals. Whether it’s 0.2 + 0.4 turning into 0.6000000000000001 or a calculation that doesn’t quite match what you expect, these quirks are a result of how computers store numbers in binary.

To handle floating-point precision in Python, you can:

  • Use math.isclose() to compare numbers
  • Round numbers before comparing
  • Use the decimal module for exact precision
  • Avoid floating-point arithmetic in sensitive calculations

By understanding how floating-point numbers work and using these techniques, you can avoid unexpected behavior in your code and write programs that handle numbers with precision and reliability.

Why don’t floating-point numbers ever make good bakers? 🍞

Because they can never measure out exactly 0.1 cups of flour! 👩‍🍳🔢 Every time they try, they end up with 0.1000000000000001 cups instead! 😅

Playwright CLI Flags Tutorial

5 Playwright CLI Flags That Will Transform Your Testing Workflow

  • 0:56 --last-failed: Zero in on just the tests that failed in your previous run
  • 2:34 --only-changed: Test only the spec files you've modified in git
  • 4:27 --repeat-each: Run tests multiple times to catch flaky behavior before it reaches production
  • 5:15 --forbid-only: Prevent accidental test.only commits from breaking your CI pipeline
  • 5:51 --ui --headed --workers 1: Debug visually with browser windows and sequential test execution

Learn how these powerful command-line options can save you time, strengthen your test suite, and streamline your Playwright testing experience. Click on any timestamp above to jump directly to that section in the tutorial!

Watch Full Video 📹️

Top comments (0)

AWS Security LIVE!

Tune in for AWS Security LIVE!

Join AWS Security LIVE! for expert insights and actionable tips to protect your organization and keep security teams prepared.

Learn More

👋 Kindness is contagious

If you found this post useful, please drop a ❤️ or leave a kind comment!

Okay