We have the details documented about compilers.
This is a case of floating point precision. Both single and double precision floating point numbers have them.
When it comes to floating point precision, there are a lot of details here
-
A
uint32_thas 32 bits, and can store all the numbers between [0,4294967296] or 0 - 2^32 -
An
int32_talso has 32 bits, can store all the numbers between [-2147483648,2147483647]. The Most Significant Bit is used to store the sign. -
A single precision float has 32 bits (format IEEE 754) and spans the range [1.2E-38, 3.4E+38]
IEEE 754 format
Also 3.4E+38 is way larger than 2147483647, so how does a float manage to store that into 32 bits.
While the int32_t can represent all numbers in its range, the float has to also somehow store decimals.
As you can imagine, there is a tradeoff and it’s with regards to precision.
The 32 bits are divided like so:
- 1 sign bit
- 8 exponent bits
- 23 mantissa bits
Exponent (range) bits
These bits represent the power-of-two exponent, or the range of numbers represented. Or perhaps a sliding window
E.g. [0.5,1], [1,2], [2,4], [4,8], [8,16] and so on
Mantissa (fraction) bits
Once you’ve found your range, e.g. [2,4], the floating point divides that by 2^23 = 8388608
(4 - 2) / 8388608 = 0.0000002384185791
This means that the precision in the range [2,4] is 0.0000002384185791. That is, the step between two consecutive floats is 0.0000002384185791.
For the range [8192,16384] the precision is
(16384 - 8192) / 8388608 = 0,0009765625
Fabien Sanglard does an excellent explanation
Your number: 1553138135
This is a big number.
The range for 1553138135 is [2^30,2^31] = [1073741824, 2147483648] (log2(1553138135) ~= 30.53)
You might notice that you’re having an upper limit in your range of 2^31. That’s almost the upper limit for unsigned integers!
But, as we mentioned, the upper limit of a single float precision number is 3.4E+38, so we’re good.
The precision, between consecutive valid floats, is calculated again:
(2147483648 - 1073741824) / 8388608 = 128
So, in that range the the difference between two consecutive floats is 128.
Your number 1553138135 is not evenly divisible by 128:
(1553138135 - 1073741824) / 128 = 3745283,6796875
Rounding that number to 3745284 and convert back:
3745284 * 128 + 1073741824 = 1553138176
Et voilà, 1553138176 is the number you got.