IEEE-754 encoding of binary floating-point data
From Coq Require Import Lia.
Require Import Core Digits Binary.
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.
Lemma join_bits_range :
forall s m e,
(0 <=
m < 2^
mw)%
Z ->
(0 <=
e < 2^
ew)%
Z ->
(0 <=
join_bits s m e < 2 ^ (
mw +
ew + 1))%
Z.
Proof.
intros s m e Hm He.
assert (0 <= mw)%Z as Hmw.
destruct mw as [|mw'|mw'] ; try easy.
clear -Hm ; simpl in Hm ; lia.
assert (0 <= ew)%Z as Hew.
destruct ew as [|ew'|ew'] ; try easy.
clear -He ; simpl in He ; lia.
unfold join_bits.
rewrite Z.shiftl_mul_pow2 by easy.
split.
- apply (Zplus_le_compat 0 _ 0) with (2 := proj1 Hm).
rewrite <- (Zmult_0_l (2^mw)).
apply Zmult_le_compat_r.
case s.
clear -He ; lia.
now rewrite Zmult_0_l.
clear -Hm ; lia.
- apply Z.lt_le_trans with (((if s then 2 ^ ew else 0) + e + 1) * 2 ^ mw)%Z.
rewrite (Zmult_plus_distr_l _ 1).
apply Zplus_lt_compat_l.
now rewrite Zmult_1_l.
rewrite <- (Zplus_assoc mw), (Zplus_comm mw), Zpower_plus.
apply Zmult_le_compat_r.
rewrite Zpower_plus by easy.
change (2^1)%Z with 2%Z.
case s ; clear -He ; lia.
clear -Hm ; lia.
clear -Hew ; lia.
easy.
Qed.
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.
Theorem split_join_bits :
forall s m e,
(0 <=
m <
Zpower 2
mw)%
Z ->
(0 <=
e <
Zpower 2
ew)%
Z ->
split_bits (
join_bits s m e) = (
s,
m,
e).
Proof.
intros s m e Hm He.
assert (0 <= mw)%Z as Hmw.
destruct mw as [|mw'|mw'] ; try easy.
clear -Hm ; simpl in Hm ; lia.
assert (0 <= ew)%Z as Hew.
destruct ew as [|ew'|ew'] ; try easy.
clear -He ; simpl in He ; lia.
unfold split_bits, join_bits.
rewrite Z.shiftl_mul_pow2 by easy.
apply f_equal2 ; [apply f_equal2|].
- case s.
+ apply Zle_bool_true.
apply Zle_0_minus_le.
ring_simplify.
apply Zplus_le_0_compat.
apply Zmult_le_0_compat.
apply He.
clear -Hm ; lia.
apply Hm.
+ apply Zle_bool_false.
apply Zplus_lt_reg_l with (2^mw * (-e))%Z.
replace (2 ^ mw * - e + ((0 + e) * 2 ^ mw + m))%Z with (m * 1)%Z by ring.
rewrite <- Zmult_plus_distr_r.
apply Z.lt_le_trans with (2^mw * 1)%Z.
now apply Zmult_lt_compat_r.
apply Zmult_le_compat_l.
clear -He ; lia.
clear -Hm ; lia.
- rewrite Zplus_comm.
rewrite Z_mod_plus_full.
now apply Zmod_small.
- rewrite Z_div_plus_full_l by (clear -Hm ; lia).
rewrite Zdiv_small with (1 := Hm).
rewrite Zplus_0_r.
case s.
+ replace (2^ew + e)%Z with (e + 1 * 2^ew)%Z by ring.
rewrite Z_mod_plus_full.
now apply Zmod_small.
+ now apply Zmod_small.
Qed.
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.
Proof.
unfold prec.
apply Zle_lt_succ.
now apply Zlt_le_weak.
Qed.
Let Hm_gt_0 : (0 < 2^
mw)%
Z.
Proof.
apply (Zpower_gt_0 radix2).
now apply Zlt_le_weak.
Qed.
Let He_gt_0 : (0 < 2^
ew)%
Z.
Proof.
apply (Zpower_gt_0 radix2).
now apply Zlt_le_weak.
Qed.
Hypothesis Hmax : (
prec <
emax)%
Z.
Theorem join_split_bits :
forall x,
(0 <=
x <
Zpower 2 (
mw +
ew + 1))%
Z ->
let '(
s,
m,
e) :=
split_bits x in
join_bits s m e =
x.
Proof.
intros x Hx.
unfold split_bits, join_bits.
rewrite Z.shiftl_mul_pow2 by now apply Zlt_le_weak.
pattern x at 4 ; rewrite Z_div_mod_eq_full with x (2^mw)%Z.
apply (f_equal (fun v => (v + _)%Z)).
rewrite Zmult_comm.
apply f_equal.
pattern (x / (2^mw))%Z at 2 ; rewrite Z_div_mod_eq_full with (x / (2^mw))%Z (2^ew)%Z.
apply (f_equal (fun v => (v + _)%Z)).
replace (x / 2 ^ mw / 2 ^ ew)%Z with (if Zle_bool (2 ^ mw * 2 ^ ew) x then 1 else 0)%Z.
case Zle_bool.
now rewrite Zmult_1_r.
now rewrite Zmult_0_r.
rewrite Zdiv_Zdiv.
apply sym_eq.
case Zle_bool_spec ; intros Hs.
apply Zle_antisym.
cut (x / (2^mw * 2^ew) < 2)%Z. clear ; lia.
apply Zdiv_lt_upper_bound.
now apply Zmult_lt_0_compat.
rewrite <- Zpower_exp ; try ( apply Z.le_ge ; apply Zlt_le_weak ; assumption ).
change 2%Z at 1 with (Zpower 2 1).
rewrite <- Zpower_exp.
now rewrite Zplus_comm.
discriminate.
apply Z.le_ge.
now apply Zplus_le_0_compat ; apply Zlt_le_weak.
apply Zdiv_le_lower_bound.
now apply Zmult_lt_0_compat.
now rewrite Zmult_1_l.
apply Zdiv_small.
now split.
now apply Zlt_le_weak.
now apply Zlt_le_weak.
now apply Zgt_not_eq.
now apply Zgt_not_eq.
Qed.
Theorem split_bits_inj :
forall x y,
(0 <=
x <
Zpower 2 (
mw +
ew + 1))%
Z ->
(0 <=
y <
Zpower 2 (
mw +
ew + 1))%
Z ->
split_bits x =
split_bits y ->
x =
y.
Proof.
intros x y Hx Hy.
generalize (join_split_bits x Hx) (join_split_bits y Hy).
destruct (split_bits x) as ((sx, mx), ex).
destruct (split_bits y) as ((sy, my), ey).
intros Jx Jy H. revert Jx Jy.
inversion_clear H.
intros Jx Jy.
now rewrite <- Jx.
Qed.
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.
Theorem split_bits_of_binary_float_correct :
forall x,
split_bits (
bits_of_binary_float x) =
split_bits_of_binary_float x.
Proof.
intros [sx|sx|sx plx Hplx|sx mx ex Hx] ;
try ( simpl ; apply split_join_bits ; split ; try apply Z.le_refl ; try apply Zlt_pred ; trivial ; lia ).
simpl. apply split_join_bits; split; try (zify; lia).
destruct (digits2_Pnat_correct plx).
unfold nan_pl in Hplx.
rewrite Zpos_digits2_pos, <- Z_of_nat_S_digits2_Pnat in Hplx.
rewrite Zpower_nat_Z in H0.
eapply Z.lt_le_trans. apply H0.
change 2%Z with (radix_val radix2). apply Zpower_le.
rewrite Z.ltb_lt in Hplx.
unfold prec in *. zify; lia.
unfold bits_of_binary_float, split_bits_of_binary_float.
assert (Hf: (emin <= ex /\ Zdigits radix2 (Zpos mx) <= prec)%Z).
destruct (andb_prop _ _ Hx) as (Hx', _).
unfold canonical_mantissa in Hx'.
rewrite Zpos_digits2_pos in Hx'.
generalize (Zeq_bool_eq _ _ Hx').
unfold FLT_exp.
unfold emin.
clear ; zify ; lia.
case Zle_bool_spec ; intros H ;
[ apply -> Z.le_0_sub in H | apply -> Z.lt_sub_0 in H ] ;
apply split_join_bits ; try now split.
split.
clear -He_gt_0 H ; lia.
cut (Zpos mx < 2 * 2^mw)%Z. clear ; lia.
replace (2 * 2^mw)%Z with (2^prec)%Z.
apply (Zpower_gt_Zdigits radix2 _ (Zpos mx)).
apply Hf.
unfold prec.
rewrite Zplus_comm.
apply Zpower_exp ; apply Z.le_ge.
discriminate.
now apply Zlt_le_weak.
split.
generalize (proj1 Hf).
clear ; lia.
destruct (andb_prop _ _ Hx) as (_, Hx').
unfold emin.
replace (2^ew)%Z with (2 * emax)%Z.
generalize (Zle_bool_imp_le _ _ Hx').
clear ; lia.
apply sym_eq.
rewrite (Zsucc_pred ew).
unfold Z.succ.
rewrite Zplus_comm.
apply Zpower_exp ; apply Z.le_ge.
discriminate.
now apply Zlt_0_le_0_pred.
Qed.
Theorem bits_of_binary_float_range:
forall x, (0 <=
bits_of_binary_float x < 2^(
mw+
ew+1))%
Z.
Proof.
unfold bits_of_binary_float.
intros [sx|sx|sx pl pl_range|sx mx ex H].
- apply join_bits_range ; now split.
- apply join_bits_range.
now split.
clear -He_gt_0 ; lia.
- apply Z.ltb_lt in pl_range.
apply join_bits_range.
split.
easy.
apply (Zpower_gt_Zdigits radix2 _ (Zpos pl)).
apply Z.lt_succ_r.
now rewrite <- Zdigits2_Zdigits.
clear -He_gt_0 ; lia.
- unfold bounded in H.
apply Bool.andb_true_iff in H ; destruct H as [A B].
apply Z.leb_le in B.
unfold canonical_mantissa, FLT_exp in A. apply Zeq_bool_eq in A.
case Zle_bool_spec ; intros H.
+ apply join_bits_range.
* split.
clear -H ; lia.
rewrite Zpos_digits2_pos in A.
cut (Zpos mx < 2 ^ prec)%Z.
unfold prec.
rewrite Zpower_plus by (clear -Hmw ; lia).
change (2^1)%Z with 2%Z.
clear ; lia.
apply (Zpower_gt_Zdigits radix2 _ (Zpos mx)).
clear -A ; zify ; lia.
* split.
unfold emin ; clear -A ; zify ; lia.
replace ew with ((ew - 1) + 1)%Z by ring.
rewrite Zpower_plus by (clear - Hew ; lia).
unfold emin, emax in *.
change (2^1)%Z with 2%Z.
clear -B ; lia.
+ apply -> Z.lt_sub_0 in H.
apply join_bits_range ; now split.
Qed.
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
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
end
else
match (
mx +
Zpower 2
mw)%
Z with
|
Zpos px =>
F754_finite sx px (
ex +
emin - 1)
|
_ =>
F754_nan false xH
end.
Lemma binary_float_of_bits_aux_correct :
forall x,
valid_binary prec emax (
binary_float_of_bits_aux x) =
true.
Proof.
intros x.
unfold binary_float_of_bits_aux, split_bits.
assert (Hnan: nan_pl prec 1 = true).
apply Z.ltb_lt.
simpl. unfold prec.
clear -Hmw ; lia.
case Zeq_bool_spec ; intros He1.
case_eq (x mod 2^mw)%Z ; try easy.
intros px Hm.
assert (Zdigits radix2 (Zpos px) <= mw)%Z.
apply Zdigits_le_Zpower.
simpl.
rewrite <- Hm.
eapply Z_mod_lt.
now apply Z.lt_gt.
apply bounded_canonical_lt_emax ; try assumption.
unfold canonical, cexp.
fold emin.
rewrite mag_F2R_Zdigits. 2: discriminate.
unfold Fexp, FLT_exp.
apply sym_eq.
apply Zmax_right.
clear -H Hprec.
unfold prec ; lia.
apply Rnot_le_lt.
intros H0.
refine (_ (mag_le radix2 _ _ _ H0)).
rewrite mag_bpow.
rewrite mag_F2R_Zdigits. 2: discriminate.
unfold emin, prec.
apply Zlt_not_le.
cut (0 < emax)%Z. clear -H Hew ; lia.
apply (Zpower_gt_0 radix2).
clear -Hew ; lia.
apply bpow_gt_0.
case Zeq_bool_spec ; intros He2.
case_eq (x mod 2 ^ mw)%Z; try easy.
intros plx Eqplx. apply Z.ltb_lt.
rewrite Zpos_digits2_pos.
assert (forall a b, a <= b -> a < b+1)%Z by (intros; lia). apply H. clear H.
apply Zdigits_le_Zpower. simpl.
rewrite <- Eqplx. edestruct Z_mod_lt; eauto.
change 2%Z with (radix_val radix2).
apply Z.lt_gt, Zpower_gt_0. lia.
case_eq (x mod 2^mw + 2^mw)%Z ; try easy.
intros px Hm.
assert (prec = Zdigits radix2 (Zpos px)).
rewrite Zdigits_mag. 2: discriminate.
apply sym_eq.
apply mag_unique.
rewrite <- abs_IZR.
unfold Z.abs.
replace (prec - 1)%Z with mw by ( unfold prec ; ring ).
rewrite <- IZR_Zpower with (1 := Zlt_le_weak _ _ Hmw).
rewrite <- IZR_Zpower. 2: now apply Zlt_le_weak.
rewrite <- Hm.
split.
apply IZR_le.
change (radix2^mw)%Z with (0 + 2^mw)%Z.
apply Zplus_le_compat_r.
eapply Z_mod_lt.
now apply Z.lt_gt.
apply IZR_lt.
unfold prec.
rewrite Zpower_exp. 2: now apply Z.le_ge ; apply Zlt_le_weak. 2: discriminate.
rewrite <- Zplus_diag_eq_mult_2.
apply Zplus_lt_compat_r.
eapply Z_mod_lt.
now apply Z.lt_gt.
apply bounded_canonical_lt_emax ; try assumption.
unfold canonical, cexp.
rewrite mag_F2R_Zdigits. 2: discriminate.
unfold Fexp, FLT_exp.
rewrite <- H.
set (ex := ((x / 2^mw) mod 2^ew)%Z).
replace (prec + (ex + emin - 1) - prec)%Z with (ex + emin - 1)%Z by ring.
apply sym_eq.
apply Zmax_left.
revert He1.
fold ex.
cut (0 <= ex)%Z.
unfold emin.
clear ; intros H1 H2 ; lia.
eapply Z_mod_lt.
apply Z.lt_gt.
apply (Zpower_gt_0 radix2).
now apply Zlt_le_weak.
apply Rnot_le_lt.
intros H0.
refine (_ (mag_le radix2 _ _ _ H0)).
rewrite mag_bpow.
rewrite mag_F2R_Zdigits. 2: discriminate.
rewrite <- H.
apply Zlt_not_le.
unfold emin.
apply Zplus_lt_reg_r with (emax - 1)%Z.
ring_simplify.
revert He2.
set (ex := ((x / 2^mw) mod 2^ew)%Z).
cut (ex < 2^ew)%Z.
replace (2^ew)%Z with (2 * emax)%Z.
clear ; intros H1 H2 ; lia.
replace ew with (1 + (ew - 1))%Z by ring.
rewrite Zpower_exp.
apply refl_equal.
discriminate.
clear -Hew ; lia.
eapply Z_mod_lt.
apply Z.lt_gt.
apply (Zpower_gt_0 radix2).
now apply Zlt_le_weak.
apply bpow_gt_0.
Qed.
Definition binary_float_of_bits x :=
FF2B prec emax _ (
binary_float_of_bits_aux_correct x).
Theorem binary_float_of_bits_of_binary_float :
forall x,
binary_float_of_bits (
bits_of_binary_float x) =
x.
Proof.
intros x.
apply B2FF_inj.
unfold binary_float_of_bits.
rewrite B2FF_FF2B.
unfold binary_float_of_bits_aux.
rewrite split_bits_of_binary_float_correct.
destruct x as [sx|sx|sx plx Hplx|sx mx ex Bx].
apply refl_equal.
simpl.
rewrite Zeq_bool_false.
now rewrite Zeq_bool_true.
cut (1 < 2^ew)%Z. clear ; lia.
now apply (Zpower_gt_1 radix2).
simpl.
rewrite Zeq_bool_false.
rewrite Zeq_bool_true; auto.
cut (1 < 2^ew)%Z. clear ; lia.
now apply (Zpower_gt_1 radix2).
unfold split_bits_of_binary_float.
case Zle_bool_spec ; intros Hm.
rewrite Zeq_bool_false.
rewrite Zeq_bool_false.
now ring_simplify (Zpos mx - 2 ^ mw + 2 ^ mw)%Z (ex - emin + 1 + emin - 1)%Z.
destruct (andb_prop _ _ Bx) as (_, H1).
generalize (Zle_bool_imp_le _ _ H1).
unfold emin.
replace (2^ew)%Z with (2 * emax)%Z.
clear ; lia.
replace ew with (1 + (ew - 1))%Z by ring.
rewrite Zpower_exp.
apply refl_equal.
discriminate.
clear -Hew ; lia.
destruct (andb_prop _ _ Bx) as (H1, _).
generalize (Zeq_bool_eq _ _ H1).
rewrite Zpos_digits2_pos.
unfold FLT_exp, emin.
generalize (Zdigits radix2 (Zpos mx)).
clear.
intros ; zify ; lia.
rewrite Zeq_bool_true. 2: apply refl_equal.
simpl.
apply f_equal.
destruct (andb_prop _ _ Bx) as (H1, _).
generalize (Zeq_bool_eq _ _ H1).
rewrite Zpos_digits2_pos.
unfold FLT_exp, emin, prec.
apply -> Z.lt_sub_0 in Hm.
generalize (Zdigits_le_Zpower radix2 _ (Zpos mx) Hm).
generalize (Zdigits radix2 (Zpos mx)).
clear.
intros ; zify ; lia.
Qed.
Theorem bits_of_binary_float_of_bits :
forall x,
(0 <=
x < 2^(
mw+
ew+1))%
Z ->
bits_of_binary_float (
binary_float_of_bits x) =
x.
Proof.
intros x Hx.
unfold binary_float_of_bits, bits_of_binary_float.
set (Cx := binary_float_of_bits_aux_correct x).
clearbody Cx.
rewrite match_FF2B.
revert Cx.
generalize (join_split_bits x Hx).
unfold binary_float_of_bits_aux.
case_eq (split_bits x).
intros (sx, mx) ex Sx.
assert (Bm: (0 <= mx < 2^mw)%Z).
inversion_clear Sx.
apply Z_mod_lt.
now apply Z.lt_gt.
case Zeq_bool_spec ; intros He1.
case_eq mx.
intros Hm Jx _.
now rewrite He1 in Jx.
intros px Hm Jx _.
rewrite Zle_bool_false.
now rewrite <- He1.
apply <- Z.lt_sub_0.
now rewrite <- Hm.
intros px Hm _ _.
apply False_ind.
apply Zle_not_lt with (1 := proj1 Bm).
now rewrite Hm.
case Zeq_bool_spec ; intros He2.
case_eq mx; intros Hm.
now rewrite He2.
now rewrite He2.
intros. zify; lia.
case_eq (mx + 2 ^ mw)%Z.
intros Hm.
apply False_ind.
clear -Bm Hm ; lia.
intros p Hm Jx Cx.
rewrite <- Hm.
rewrite Zle_bool_true.
now ring_simplify (mx + 2^mw - 2^mw)%Z (ex + emin - 1 - emin + 1)%Z.
now ring_simplify.
intros p Hm.
apply False_ind.
clear -Bm Hm ; zify ; lia.
Qed.
End Binary_Bits.
Specialization for IEEE single precision operations
Section B32_Bits.
Arguments B754_nan {
prec} {
emax}.
Definition binary32 :=
binary_float 24 128.
Let Hprec : (0 < 24)%
Z.
Proof.
apply refl_equal.
Qed.
Let Hprec_emax : (24 < 128)%
Z.
Proof.
apply refl_equal.
Qed.
Let Hemax : (3 <= 128)%
Z.
Proof.
intros H.
discriminate H.
Qed.
Definition default_nan_pl32 : {
nan :
binary32 |
is_nan 24 128
nan =
true } :=
exist _ (@
B754_nan 24 128
false (
iter_nat xO 22
xH) (
refl_equal true)) (
refl_equal true).
Definition unop_nan_pl32 (
f :
binary32) : {
nan :
binary32 |
is_nan 24 128
nan =
true } :=
match f as f with
|
B754_nan s pl Hpl =>
exist _ (
B754_nan s pl Hpl) (
refl_equal true)
|
_ =>
default_nan_pl32
end.
Definition binop_nan_pl32 (
f1 f2 :
binary32) : {
nan :
binary32 |
is_nan 24 128
nan =
true } :=
match f1,
f2 with
|
B754_nan s1 pl1 Hpl1,
_ =>
exist _ (
B754_nan s1 pl1 Hpl1) (
refl_equal true)
|
_,
B754_nan s2 pl2 Hpl2 =>
exist _ (
B754_nan s2 pl2 Hpl2) (
refl_equal true)
|
_,
_ =>
default_nan_pl32
end.
Definition ternop_nan_pl32 (
f1 f2 f3 :
binary32) : {
nan :
binary32 |
is_nan 24 128
nan =
true } :=
match f1,
f2,
f3 with
|
B754_nan s1 pl1 Hpl1,
_,
_ =>
exist _ (
B754_nan s1 pl1 Hpl1) (
refl_equal true)
|
_,
B754_nan s2 pl2 Hpl2,
_ =>
exist _ (
B754_nan s2 pl2 Hpl2) (
refl_equal true)
|
_,
_,
B754_nan s3 pl3 Hpl3 =>
exist _ (
B754_nan s3 pl3 Hpl3) (
refl_equal true)
|
_,
_,
_ =>
default_nan_pl32
end.
Definition b32_erase :
binary32 ->
binary32 :=
erase 24 128.
Definition b32_opp :
binary32 ->
binary32 :=
Bopp 24 128
unop_nan_pl32.
Definition b32_abs :
binary32 ->
binary32 :=
Babs 24 128
unop_nan_pl32.
Definition b32_pred :
binary32 ->
binary32 :=
Bpred _ _ Hprec Hprec_emax Hemax unop_nan_pl32.
Definition b32_succ :
binary32 ->
binary32 :=
Bsucc _ _ Hprec Hprec_emax Hemax unop_nan_pl32.
Definition b32_sqrt :
mode ->
binary32 ->
binary32 :=
Bsqrt _ _ Hprec Hprec_emax unop_nan_pl32.
Definition b32_plus :
mode ->
binary32 ->
binary32 ->
binary32 :=
Bplus _ _ Hprec Hprec_emax binop_nan_pl32.
Definition b32_minus :
mode ->
binary32 ->
binary32 ->
binary32 :=
Bminus _ _ Hprec Hprec_emax binop_nan_pl32.
Definition b32_mult :
mode ->
binary32 ->
binary32 ->
binary32 :=
Bmult _ _ Hprec Hprec_emax binop_nan_pl32.
Definition b32_div :
mode ->
binary32 ->
binary32 ->
binary32 :=
Bdiv _ _ Hprec Hprec_emax binop_nan_pl32.
Definition b32_fma :
mode ->
binary32 ->
binary32 ->
binary32 ->
binary32 :=
Bfma _ _ Hprec Hprec_emax ternop_nan_pl32.
Definition b32_compare :
binary32 ->
binary32 ->
option comparison :=
Bcompare 24 128.
Definition b32_of_bits :
Z ->
binary32 :=
binary_float_of_bits 23 8 (
refl_equal _) (
refl_equal _) (
refl_equal _).
Definition bits_of_b32 :
binary32 ->
Z :=
bits_of_binary_float 23 8.
End B32_Bits.
Specialization for IEEE double precision operations
Section B64_Bits.
Arguments B754_nan {
prec} {
emax}.
Definition binary64 :=
binary_float 53 1024.
Let Hprec : (0 < 53)%
Z.
Proof.
apply refl_equal.
Qed.
Let Hprec_emax : (53 < 1024)%
Z.
Proof.
apply refl_equal.
Qed.
Let Hemax : (3 <= 1024)%
Z.
Proof.
intros H.
discriminate H.
Qed.
Definition default_nan_pl64 : {
nan :
binary64 |
is_nan 53 1024
nan =
true } :=
exist _ (@
B754_nan 53 1024
false (
iter_nat xO 51
xH) (
refl_equal true)) (
refl_equal true).
Definition unop_nan_pl64 (
f :
binary64) : {
nan :
binary64 |
is_nan 53 1024
nan =
true } :=
match f as f with
|
B754_nan s pl Hpl =>
exist _ (
B754_nan s pl Hpl) (
refl_equal true)
|
_ =>
default_nan_pl64
end.
Definition binop_nan_pl64 (
f1 f2 :
binary64) : {
nan :
binary64 |
is_nan 53 1024
nan =
true } :=
match f1,
f2 with
|
B754_nan s1 pl1 Hpl1,
_ =>
exist _ (
B754_nan s1 pl1 Hpl1) (
refl_equal true)
|
_,
B754_nan s2 pl2 Hpl2 =>
exist _ (
B754_nan s2 pl2 Hpl2) (
refl_equal true)
|
_,
_ =>
default_nan_pl64
end.
Definition ternop_nan_pl64 (
f1 f2 f3 :
binary64) : {
nan :
binary64 |
is_nan 53 1024
nan =
true } :=
match f1,
f2,
f3 with
|
B754_nan s1 pl1 Hpl1,
_,
_ =>
exist _ (
B754_nan s1 pl1 Hpl1) (
refl_equal true)
|
_,
B754_nan s2 pl2 Hpl2,
_ =>
exist _ (
B754_nan s2 pl2 Hpl2) (
refl_equal true)
|
_,
_,
B754_nan s3 pl3 Hpl3 =>
exist _ (
B754_nan s3 pl3 Hpl3) (
refl_equal true)
|
_,
_,
_ =>
default_nan_pl64
end.
Definition b64_erase :
binary64 ->
binary64 :=
erase 53 1024.
Definition b64_opp :
binary64 ->
binary64 :=
Bopp 53 1024
unop_nan_pl64.
Definition b64_abs :
binary64 ->
binary64 :=
Babs 53 1024
unop_nan_pl64.
Definition b64_pred :
binary64 ->
binary64 :=
Bpred _ _ Hprec Hprec_emax Hemax unop_nan_pl64.
Definition b64_succ :
binary64 ->
binary64 :=
Bsucc _ _ Hprec Hprec_emax Hemax unop_nan_pl64.
Definition b64_sqrt :
mode ->
binary64 ->
binary64 :=
Bsqrt _ _ Hprec Hprec_emax unop_nan_pl64.
Definition b64_plus :
mode ->
binary64 ->
binary64 ->
binary64 :=
Bplus _ _ Hprec Hprec_emax binop_nan_pl64.
Definition b64_minus :
mode ->
binary64 ->
binary64 ->
binary64 :=
Bminus _ _ Hprec Hprec_emax binop_nan_pl64.
Definition b64_mult :
mode ->
binary64 ->
binary64 ->
binary64 :=
Bmult _ _ Hprec Hprec_emax binop_nan_pl64.
Definition b64_div :
mode ->
binary64 ->
binary64 ->
binary64 :=
Bdiv _ _ Hprec Hprec_emax binop_nan_pl64.
Definition b64_fma :
mode ->
binary64 ->
binary64 ->
binary64 ->
binary64 :=
Bfma _ _ Hprec Hprec_emax ternop_nan_pl64.
Definition b64_compare :
binary64 ->
binary64 ->
option comparison :=
Bcompare 53 1024.
Definition b64_of_bits :
Z ->
binary64 :=
binary_float_of_bits 52 11 (
refl_equal _) (
refl_equal _) (
refl_equal _).
Definition bits_of_b64 :
binary64 ->
Z :=
bits_of_binary_float 52 11.
End B64_Bits.