I recently started using Julia and I came upon the bits
function, which returns the bit-string representation of its numeric argument. For example:
julia> bits(1.0)
"0011111111110000000000000000000000000000000000000000000000000000"
However, while playing with this function, I was surprised to discover that bits
returns very different bit strings for 1.0
and 2.0
:
julia> bits(1.0)
"0011111111110000000000000000000000000000000000000000000000000000"
julia> bits(2.0)
"0100000000000000000000000000000000000000000000000000000000000000"
I would have expected those two values to be similar...
What is the meaning of those bits? I vaguely recall something about bits encoding the exponent (from my numerical-analysis class), but I really do not remember it well and I did not manage to find a good description online...
To understand why the
ASCIIString
values ofbits(1.0)
andbits(2.0)
are "so different", you need to know a bit (!) about IEEE-754 (binary) floating-point numbers. Each such double-precision number is stored as a 64-bit word, broken down into three parts:The value of a normalized number (such as
1.0
and2.0
) can be obtained by using the following formula:(For double-precision floating-point numbers, the bias has a value of 2^10 - 1 = 1023)
Now,
1.0 = +1.000... x 2^(1023 - bias)
and 1023 corresponds to (0)1111111111 in base 2, so the corresponding bit string is
2.0 = +1.000... x 2^(1024 - bias)
and 1024 corresponds to 10000000000 in base 2, so the corresponding bit string is
3.0 = +1.100... x 2^(1024 - bias)
so the corresponding bit string is
etc.
In summary, you can obtain the bit string of
2.0
by incrementing the biased-exponent part in the bit string of1.0
, which is a power of 2, minus 1. Incrementing such a number causes all the bits of its binary representation to change, in the same way that incrementing the number 9999 (in decimal representation) causes all the digits to change.