Float methods `from_bits`/`to_bits` and constants for minimum denormal representable value

  {% for bits in [32,64] %}
  struct ::Float{{bits}}
    def self.from_bits(bits : ::UInt{{bits}})
      pointerof(bits).as(::Float{{bits}}*).value
    end
    def to_bits : ::UInt{{bits}}
      bits = self # because "can't take address of self"
      pointerof(bits).as(::UInt{{bits}}*).value
    end
    MIN_POSITIVE_DENORMAL = from_bits(1)
  end
  {% end %}
  # pardon the humor -- and the two `bits` variables
  raise "hell" unless ::Float32::MIN_POSITIVE_DENORMAL == 1.4e-45_f32
  raise "hell" unless ::Float32::MIN_POSITIVE_DENORMAL.to_bits == 1_u32
  raise "hell" unless ::Float64::MIN_POSITIVE_DENORMAL == 4.9E-324_f64
  raise "hell" unless ::Float64::MIN_POSITIVE_DENORMAL.to_bits == 1_u64

Because why not.

1 Like

Nice! Take a look at the unsafe_as method in the standard library.

2 Likes

Oops… thanks, I missed the unsafe_as.
So it’s just bits.unsafe_as(::Float{{bits}}) and self.unsafe_as(::UInt{{bits}})

I still think it’s nice to have more descriptive names. I was just suggesting a simplification :-)

2 Likes