After doing a lot of research and calculations, I came to the conclusion that this is not a bug. This is math: floating point arithmetic. Let’s dig deeper to understand what’s going on behind the scenes.
Problem statement: how did it happen that 0.1 + 0.2 = 0.30000000000000004?
Well, if you’ve programmed in languages like Java or C, you should be aware of the different data types used to store values. In the upcoming discussion, we will consider two types of data: integers and floating-point numbers.
Integer data types store integers, while floating-point data types store fractional numbers.
Before we continue, let’s take a look at one small concept:: how are numbers represented for computational purposes? Very small and very large numbers are usually stored in an exponential representation. They are represented as:
In addition, a number is normalized if it is written in an exponential representation with one nonzero decimal digit before the decimal point. For example, the number 0.0005606 in exponential representation and normalized will be represented as:
Significantis the number of significant digits that do not include zeros, and the base represents the base system used, which here is decimal (10). The exponent represents the number of places that you need to move the number point to the left or right for correct representation.
Now there are two ways to display numbers in floating-point arithmetic: single precision and double precision. Single precision uses 32 bits, and double precision uses 64 bits for floating-point arithmetic.
In this format, numbers are stored in 64 bits, where the number (fraction) is stored in bits 0 to 51, the exponent is stored in bits 52 to 62, and the sign is stored in bits 63.
Let’s represent 0.1 in 64-bit format according to the IEEE754 standard.
The first step is to convert (0,1) base 10 to its binary equivalent (base 2).
To do this, we start by multiplying 0.1 by 2 and separate the digit before the decimal to get the binary equivalent.
After repeating this for 64 bits, we’re going to arrange them in ascending order to get the mantissa, which we’re going to round up to 52 bits according to the double-precision standard.
Representing it in scientific form and rounding it up to the first 52 bits, we get:
Part of the mantissa is ready. Now, for the exponent, we will use the following calculation:
Here, 11 represents the number of bits we are going to use for the 64-bit representation of the exponent, and -4 represents the exponent from the scientific notation.
Final representation of the number 0,1:
Similarly, 0.2 will be represented as:
Adding two after the exponents are the same for both will give us:
In floating point representation, this becomes:
This is represented as 0.1 + 0.2.
This is the reason for getting 0.1 + 0.2 = 0,30000000000000004.