Android float arithmetic wrong(SOLVED)

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_t has 32 bits, and can store all the numbers between [0,4294967296] or 0 - 2^32

  • An int32_t also 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.

6 Likes