0.1 is not 0.1. Yups!
Computers can't store 0.1 accurately. It is stored as 0.1000000015! In this post we explore and take a look at what is really going on.
Don't trust me? Dont have to. Compile and run the following C code
#include <stdio.h>
void main() {
float value = 0.1;
printf("value: %0.10f\n", value);
}
Assuming the code above is saved in main.c, you can compile and run the compiled code as shown below -
~/
❯ gcc main.c
~/
❯ ./a.out
0.1000000015
Computers don't store 0.1 as 0.1? That is correct!
How is 0.1 represented?
Try another experiment. Compile and run the following -
#include <stdio.h>
void main() {
float value = 0.1;
printf("value: %0.10f\n", value);
printf("In Hex: 0x%x\n", *(unsigned int *)&value);
}
I see the following output.
~/
❯ gcc main.c
~/
❯ ./a.out
value: 0.1000000015
In Hex: 0x3dcccccd
Say hello to - IEEE 754 floating-point format :)
A floating-point number is typically represented using the IEEE 754
standard for single-precision floating-point format. This format uses 32 bits (or 4 bytes) of memory to represent a floating-point number.
The single-precision floating-point format consists of three parts: the sign bit, the exponent, and the mantissa (also known as the significand).
The exponent is an 8-bit
field that represents the magnitude of the number. It is biased by 127
, which means that an exponent of 0
represents a very small number (close to zero), while an exponent of 255
represents a very large number (such as infinity).
The mantissa is a 23-bit
field that represents the significant digits of the number. It includes the fractional part of the number and is used to store the precision of the number.
xxx..
in 1.xxx...
and that, every number is reduced to 1.something
and the exponent is adjust accordingly.Back to 0x3dcccccd
32-bit
representation of the number 0.1
using the single-precision floating-point format: 0x3dcccccd(hex)
which in binary translates to -
0
01111011
10011001100110011001101
Breaking this down, we can see that:
- The sign bit is
0
, which means that the first bit is0
. - The exponent is
01111011
, which represents123
in decimal. Adding the bias of127
gives us an exponent of-4
. - The mantissa is
10011001100110011001101
. To convert this to decimal, we can interpret it as a binary fraction by placing a binary point at the left end and multiplying each bit by the corresponding power of two:
0 01111011 10011001100110011001101
= 1.10011001100110011001101(binary) x 2^-4
= 1.60000002384(decimal) x 2^-4
= 0.1000000015(decimal)
Try
There are many more decimal numbers that cannot be represented accurately. Can you guess some?
Discussion