Section operations.
Variable radix : Z.
Let FtoRradix := FtoR radix.
Local Coercion FtoRradix : float >-> R.
Hypothesis radixNotZero : (0 < radix)%Z.
Definition Fplus (x y : float) :=
Float
(Fnum x * Zpower_nat radix (Z.abs_nat (Fexp x - Z.min (Fexp x) (Fexp y))) +
Fnum y * Zpower_nat radix (Z.abs_nat (Fexp y - Z.min (Fexp x) (Fexp y))))
(Z.min (Fexp x) (Fexp y)).
intros x y; unfold Fplus, Fshift, FtoRradix, FtoR in |- *; simpl in |- *.
rewrite plus_IZR.
rewrite Rmult_comm; rewrite Rmult_plus_distr_l; auto.
repeat rewrite Rmult_IZR.
repeat rewrite (Rmult_comm (Fnum x)); repeat rewrite (Rmult_comm (Fnum y)).
repeat rewrite Zpower_nat_Z_powerRZ; auto.
repeat rewrite <- Rmult_assoc.
repeat rewrite <- powerRZ_add; auto with real zarith arith.
repeat rewrite inj_abs; auto with real zarith.
repeat rewrite Zplus_minus; auto.
Qed.
Definition Fopp (x : float) := Float (- Fnum x) (Fexp x).
unfold FtoRradix, FtoR, Fopp in |- *; simpl in |- *.
intros x.
rewrite Ropp_Ropp_IZR; auto with real.
Qed.
intros p; case p; unfold Fopp in |- *; simpl in |- *; auto.
intros; rewrite Z.opp_involutive; auto.
Qed.
intros f; case f; intros n e; case n; unfold is_Fzero in |- *; simpl in |- *;
auto with zarith; intros; red in |- *; intros; discriminate.
Qed.
intros x; unfold Fopp, Fdigit in |- *; simpl in |- *.
rewrite <- (digit_abs radix (- Fnum x)).
rewrite <- (digit_abs radix (Fnum x)).
case (Fnum x); simpl in |- *; auto.
Qed.
Definition Fabs (x : float) := Float (Z.abs (Fnum x)) (Fexp x).
intros x; case x; unfold FtoRradix, FtoR in |- *; simpl in |- *.
intros Fnum1 Fexp1 H'.
repeat rewrite <- (Rmult_comm (powerRZ radix Fexp1)); apply Rmult_eq_compat_l;
auto.
cut (0 <= Fnum1)%Z.
unfold Z.abs, Z.le in |- *.
case Fnum1; simpl in |- *; auto.
intros p H'0; case H'0; auto.
apply Znot_gt_le; auto.
Contradict H'.
apply Rgt_not_le; auto.
rewrite Rmult_comm.
replace 0%R with (powerRZ radix Fexp1 * 0)%R; auto with real.
red in |- *; apply Rmult_lt_compat_l; auto with real zarith.
Qed.
intros x; case x; unfold FtoRradix, FtoR in |- *; simpl in |- *.
intros Fnum1 Fexp1 H'.
rewrite <- Ropp_mult_distr_l_reverse;
repeat rewrite <- (Rmult_comm (powerRZ radix Fexp1));
apply Rmult_eq_compat_l; auto.
cut (Fnum1 <= 0)%Z.
unfold Z.abs, Z.le in |- *.
case Fnum1; unfold IZR; auto with real.
intros p H'0; case H'0; auto.
apply Znot_gt_le.
Contradict H'.
apply Rgt_not_le; auto.
rewrite Rmult_comm.
replace 0%R with (powerRZ radix Fexp1 * 0)%R; auto with real.
red in |- *; apply Rmult_lt_compat_l; auto with real arith.
replace 0%R with (IZR 0); auto with real zarith arith.
Qed.

Theorem Fabs_correct : forall x : float, Fabs x = Rabs x :>R.