Section Extra_ops.
(** [prec] is the number of bits of the mantissa including the implicit one. [emax] is the exponent of the infinities. Typically p=24 and emax = 128 in single precision. *)
Variable prec emax : Z.
Context (prec_gt_0_ : Prec_gt_0 prec).
Let emin := (3 - emax - prec)%Z.
Let fexp := FLT_exp emin prec.
Hypothesis Hmax : (prec < emax)%Z.
Let binary_float := binary_float prec emax.
(** Remarks on [is_finite] *)
Remark is_finite_not_is_nan:
forall (f: binary_float), is_finite _ _ f = true -> is_nan _ _ f = false.
Remark is_finite_strict_finite:
forall (f: binary_float), is_finite_strict _ _ f = true -> is_finite _ _ f = true.
(** Digression on FP numbers that cannot be [-0.0]. *)
Definition is_finite_pos0 (f: binary_float) : bool :=
match f with
| B754_zero _ _ s => negb s
| B754_infinity _ _ _ => false
| B754_nan _ _ _ _ _ => false
| B754_finite _ _ _ _ _ _ => true
end.
(** ** Decidable equality *)
Definition Beq_dec: forall (f1 f2: binary_float), {f1 = f2} + {f1 <> f2}.
(** Conversion from an integer.  Round to nearest. *)
Definition BofZ (n: Z) : binary_float :=
binary_normalize prec emax prec_gt_0_ Hmax mode_NE n 0 false.
(** Commutation properties with addition, subtraction, multiplication. *)
(** Rounding to odd the argument of [BofZ]. *)
Definition int_round_odd (x: Z) (p: Z) :=
(if Z.eqb (x mod 2^p) 0 || Z.odd (x / 2^p) then x / 2^p else x / 2^p + 1) * 2^p.
(** ** Conversion from a FP number to an integer *)
(** Always rounds toward zero. *)
Definition ZofB (f: binary_float): option Z :=
match f with
| B754_finite _ _ s m (Zpos e) _ => Some (cond_Zopp s (Zpos m) * Z.pow_pos radix2 e)%Z
| B754_finite _ _ s m 0 _ => Some (cond_Zopp s (Zpos m))
| B754_finite _ _ s m (Zneg e) _ => Some (cond_Zopp s (Zpos m / Z.pow_pos radix2 e))%Z
| B754_zero _ _ _ => Some 0%Z
| _ => None
end.

Theorem ZofB_correct:
forall f,
ZofB f = if is_finite _ _ f then Some (Ztrunc (B2R _ _ f)) else None.