Section Binary_Bits.
Arguments exist {A} {P}.
Arguments B754_zero {prec} {emax}.
Arguments B754_infinity {prec} {emax}.
Arguments B754_nan {prec} {emax}.
Arguments B754_finite {prec} {emax}.
(** Number of bits for the fraction and exponent *)
Variable mw ew : Z.
Definition join_bits (s : bool) m e :=
(Z.shiftl ((if s then Zpower 2 ew else 0) + e) mw + m)%Z.
Definition split_bits x :=
let mm := Zpower 2 mw in
let em := Zpower 2 ew in
(Zle_bool (mm * em) x, Zmod x mm, Zmod (Z.div x mm) em)%Z.
Hypothesis Hmw : (0 < mw)%Z.
Hypothesis Hew : (0 < ew)%Z.
Let emax := Zpower 2 (ew - 1).
Let prec := (mw + 1)%Z.
Let emin := (3 - emax - prec)%Z.
Let binary_float := binary_float prec emax.
Let Hprec : (0 < prec)%Z.
Let Hm_gt_0 : (0 < 2^mw)%Z.
Let He_gt_0 : (0 < 2^ew)%Z.
Hypothesis Hmax : (prec < emax)%Z.
Definition bits_of_binary_float (x : binary_float) :=
match x with
| B754_zero sx => join_bits sx 0 0
| B754_infinity sx => join_bits sx 0 (Zpower 2 ew - 1)
| B754_nan sx plx _ => join_bits sx (Zpos plx) (Zpower 2 ew - 1)
| B754_finite sx mx ex _ =>
let m := (Zpos mx - Zpower 2 mw)%Z in
if Zle_bool 0 m then
join_bits sx m (ex - emin + 1)
else
join_bits sx (Zpos mx) 0
end.
Definition split_bits_of_binary_float (x : binary_float) :=
match x with
| B754_zero sx => (sx, 0, 0)%Z
| B754_infinity sx => (sx, 0, Zpower 2 ew - 1)%Z
| B754_nan sx plx _ => (sx, Zpos plx, Zpower 2 ew - 1)%Z
| B754_finite sx mx ex _ =>
let m := (Zpos mx - Zpower 2 mw)%Z in
if Zle_bool 0 m then
(sx, m, ex - emin + 1)%Z
else
(sx, Zpos mx, 0)%Z
end.
Definition binary_float_of_bits_aux x :=
let '(sx, mx, ex) := split_bits x in
if Zeq_bool ex 0 then
match mx with
| Z0 => F754_zero sx
| Zpos px => F754_finite sx px emin
| Zneg _ => F754_nan false xH (* dummy *)
end
else if Zeq_bool ex (Zpower 2 ew - 1) then
match mx with
| Z0 => F754_infinity sx
| Zpos plx => F754_nan sx plx
| Zneg _ => F754_nan false xH (* dummy *)
end
else
match (mx + Zpower 2 mw)%Z with
| Zpos px => F754_finite sx px (ex + emin - 1)
| _ => F754_nan false xH (* dummy *)
end.

Lemma binary_float_of_bits_aux_correct :
forall x,
valid_binary prec emax (binary_float_of_bits_aux x) = true.