Can you twiddle bits in a Float64 variable?

Can you twiddle bits in a Float64 variable?

Can you have x = 123.456
then type cast x into UInt64
Twiddle its bits
then type cast it back to Float64 to get a different Float64 number?

Just wondering.

Why don’t you try?

2 Likes

The reinterpret function could be worth a look :slight_smile:

2 Likes

ldexp does this.

1 Like
julia> xu = reinterpret(Unsigned, 1.2)
0x3ff3333333333333

julia> typeof(xu)
UInt64

julia> xu = xu + 1
0x3ff3333333333334

julia> xf = reinterpret(Float64, xu)
1.2000000000000002

julia> 

Thanks, this seems to work.

julia> xu = reinterpret(UInt64, 1.2)
0x3ff3333333333333

julia> typeof(xu)
UInt64

This seems to work as well, I wonder why it is called Unsigned instead of UInt64?

There also all thses strange masks I can muck around with

using .Base: sign_mask, exponent_mask, exponent_one,
            exponent_half, uinttype, significand_mask,
            significand_bits, exponent_bits, exponent_bias,
            exponent_max, exponent_raw_max, clamp, clamp!

Unsigned is the supertype of UInt64:

julia> supertype(UInt64), supertype(UInt32), supertype(UInt16)
(Unsigned, Unsigned, Unsigned)
1 Like

The fact that Unsigned (or Signed) works here due to some special casing (see methods(reinterpret)). It’s useful if you want to cast different width floats (Float16, Float32, Float64, or collectively Base.IEEEFloat) to Base.BitInteger with the same code, so that your bit-twiddling can work on multiple widths.

A related set of internal functions (i.e., they may not continue to work indefinitely) are:

julia> Base.uinttype(Float64), Base.inttype(Float32), Base.floattype(UInt16)
(UInt64, Int32, Float16)
1 Like