Floating point precision in C++

I've heard that floating point numbers can sometimes be imprecise in C++. Can you explain why this happens and how to handle it?

Floating point numbers in C++ (and most other languages) are often approximations due to the way they're represented in binary. This can lead to some surprising results.

In C++, float and double types are typically implemented as IEEE 754 floating point numbers. These numbers are represented in binary with a fixed number of bits for the mantissa (the fraction part) and the exponent.

Because of this fixed size representation, not all decimal numbers can be represented exactly in binary. For example, 0.1 in decimal is a repeating fraction in binary (just like how 1/3 is a repeating decimal in base 10). The binary representation of 0.1 is cut off at some point, leading to a slight inaccuracy.

Here's a famous example of this inaccuracy:

#include <iostream>

int main() {
  double a = 0.1;
  double b = 0.2;
  double c = a + b;

  std::cout << std::boolalpha;

  // Outputs "false"
  std::cout << (c == 0.3);
}
false

In this case, a + b is not exactly equal to 0.3 due to the imprecision in the binary representations of 0.1 and 0.2.

To handle this, you usually want to avoid comparing floating point numbers directly for equality. Instead, check if the difference between the numbers is less than some small threshold value (often called an epsilon):

#include <iostream>
#include <cmath>

bool almost_equal(double a, double b,
  double epsilon = 1e-8) {
  return std::abs(a - b) < epsilon;
}

int main() {
  double a = 0.1;
  double b = 0.2;
  double c = a + b;

  std::cout << std::boolalpha;

  // Outputs "true"
  std::cout << almost_equal(c, 0.3);
}
true

Another way to handle this is to use integer types for arithmetic when possible (if you're dealing with fixed-point numbers, for example), or to use a decimal library for financial calculations where exact decimal representations are crucial.

It's also worth noting that double has more precision than float (usually 64 bits vs 32 bits), so it can represent numbers more accurately. But it still suffers from the same fundamental issue of not being able to exactly represent all decimal numbers.

Variables, Types and Operators

Learn the fundamentals of C++ programming: declaring variables, using built-in data types, and performing operations with operators

Questions & Answers

Answers are generated by AI models and may not have been reviewed. Be mindful when running any code on your device.

How does integer division work in C++?
Can you explain more about how integer division and the modulus operator work in C++, with some examples?
Implicit casts between booleans and numbers in C++
The lesson mentions that numeric types can be implicitly cast to booleans in C++, with 0 being false and anything else true. Can you clarify how that works with an example?
What is uniform initialization in C++?
The lesson recommends using uniform initialization with braces (like int x {5};) instead of the = operator. What advantages does this have?
When should I use auto in C++?
The auto keyword seems convenient, but the lesson says to use it sparingly. When is it appropriate to use auto in C++?
How does operator precedence work in C++?
Can you clarify the rules around operator precedence in C++? How can I control the order of operations?
Prefix vs postfix increment in C++
What's the difference between the prefix and postfix increment/decrement operators in C++? When should I use one over the other?
Or Ask your Own Question
Get an immediate answer to your specific question using our AI assistant