tecosaur / About.jl

Mirror of https://code.tecosaur.net/tec/About.jl
Mozilla Public License 2.0
130 stars 7 forks source link

Floating point zeros and subnormals #23

Closed GunnarFarneback closed 2 weeks ago

GunnarFarneback commented 2 months ago

The illustrations of floating point numbers are amazing but some of the shown arithmetic doesn't make sense.

julia> about(0.0)
Float64 (<: AbstractFloat <: Real <: Number <: Any), occupies 8B.

 0000000000000000000000000000000000000000000000000000000000000000 
 ╨└────┬────┘└────────────────────────┬─────────────────────────┘
 +  2^-1023 ×                1.000000000000000000                
 = 0.0000000000000000e+00

 0000000000000000000000000000000000000000000000000000000000000001 
 ╨└────┬────┘└────────────────────────┬─────────────────────────┘
 +  2^-1023 ×                1.000000000000000222                
 = 4.9406564584124654e-324

With an all zeros exponent, the mantissa doesn't have a hidden leading one bit and the exponent value stays at the smallest normal exponent, so it would make more sense to explain these as + 2^-1022 × 0 and + 2^-1022 × 0.000000000000000222 respectively.

Note also that Float32 and Float16 behave differently and are off on the zero exponent.

julia> about(0.0f0)
Float32 (<: AbstractFloat <: Real <: Number <: Any), occupies 4B.

 00000000000000000000000000000000 
 ╨└──┬───┘└──────────┬──────────┘
 +2^-1023×      1.000000000      
 = 0.0000000e+00

julia> about(nextfloat(0.0f0))
Float32 (<: AbstractFloat <: Real <: Number <: Any), occupies 4B.

 00000000000000000000000000000001 
 ╨└──┬───┘└──────────┬──────────┘
 + 2^-149×      1.000000000      
 = 1.4012985e-45