(** Divisions that can be turned into multiplications by an inverse *)
Definition Bexact_inverse_mantissa := Z.iter (prec - 1) xO xH.
Remark Bexact_inverse_mantissa_value:
Zpos Bexact_inverse_mantissa = 2 ^ (prec - 1).
Remark Bexact_inverse_mantissa_digits2_pos:
Z.pos (digits2_pos Bexact_inverse_mantissa) = prec.
Remark bounded_Bexact_inverse:
forall e,
emin <= e <= emax - prec <-> bounded prec emax Bexact_inverse_mantissa e = true.
Program Definition Bexact_inverse (f: binary_float) : option binary_float :=
match f with
| B754_finite _ _ s m e B =>
if Pos.eq_dec m Bexact_inverse_mantissa then
let e' := -e - (prec - 1) * 2 in
if Z_le_dec emin e' then
if Z_le_dec e' emax then
Some(B754_finite _ _ s m e' _)
else None else None else None
| _ => None
end.
Next Obligation.
rewrite <- bounded_Bexact_inverse in B. rewrite <- bounded_Bexact_inverse.
unfold emin in *. omega.
Qed.

(* Specifications: *)
Lemma Bexact_inverse_correct:
forall f f', Bexact_inverse f = Some f' ->
is_finite_strict _ _ f = true
/\ is_finite_strict _ _ f' = true
/\ B2R _ _ f' = (/ B2R _ _ f)%R
/\ B2R _ _ f <> 0%R
/\ Bsign _ _ f' = Bsign _ _ f.
Lemma Bexact_inverse_correct:
forall f f', Bexact_inverse f = Some f' ->
is_finite_strict _ _ f = true
/\ is_finite_strict _ _ f' = true
/\ B2R _ _ f' = (/ B2R _ _ f)%R
/\ B2R _ _ f <> 0%R
/\ Bsign _ _ f' = Bsign _ _ f.