DEV Community

Cover image for Floating-Point Precision in Programming
Dilan
Dilan

Posted on • Edited on

3 1 2

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! 😅

Reinvent your career. Join DEV.

It takes one minute and is worth it for your career.

Get started

Top comments (0)

Billboard image

The Next Generation Developer Platform

Coherence is the first Platform-as-a-Service you can control. Unlike "black-box" platforms that are opinionated about the infra you can deploy, Coherence is powered by CNC, the open-source IaC framework, which offers limitless customization.

Learn more

👋 Kindness is contagious

Discover a treasure trove of wisdom within this insightful piece, highly respected in the nurturing DEV Community enviroment. Developers, whether novice or expert, are encouraged to participate and add to our shared knowledge basin.

A simple "thank you" can illuminate someone's day. Express your appreciation in the comments section!

On DEV, sharing ideas smoothens our journey and strengthens our community ties. Learn something useful? Offering a quick thanks to the author is deeply appreciated.

Okay