Definition neg_pl (s:bool) (pl:nan_pl 24) := (negb s, pl).
Definition abs_pl (s:bool) (pl:nan_pl 24) := (false, pl).
Definition binop_pl (x y: binary32) : bool*nan_pl 24 :=
match x, y with
| B754_nan s1 pl1, B754_nan s2 pl2 =>
if Archi.choose_binop_pl_32 s1 pl1 s2 pl2
then (s2, transform_quiet_pl pl2)
else (s1, transform_quiet_pl pl1)
| B754_nan s1 pl1, _ => (s1, transform_quiet_pl pl1)
| _, B754_nan s2 pl2 => (s2, transform_quiet_pl pl2)
| _, _ => Archi.default_pl_32
end.
(** ** Operations over single-precision floats *)
Definition zero: float32 := B754_zero _ _ false. (**r the float [+0.0] *)
Definition eq_dec: forall (f1 f2: float32), {f1 = f2} + {f1 <> f2} := Beq_dec _ _.
(** Arithmetic operations *)
Definition neg: float32 -> float32 := Bopp _ _ neg_pl. (**r opposite (change sign) *)
Definition abs: float32 -> float32 := Babs _ _ abs_pl. (**r absolute value (set sign to [+]) *)
Definition add: float32 -> float32 -> float32 :=
Bplus 24 128 __ __ binop_pl mode_NE. (**r addition *)
Definition sub: float32 -> float32 -> float32 :=
Bminus 24 128 __ __ binop_pl mode_NE. (**r subtraction *)
Definition mul: float32 -> float32 -> float32 :=
Bmult 24 128 __ __ binop_pl mode_NE. (**r multiplication *)
Definition div: float32 -> float32 -> float32 :=
Bdiv 24 128 __ __ binop_pl mode_NE. (**r division *)
Definition compare (f1 f2: float32) : option Datatypes.comparison := (**r general comparison *)
Bcompare 24 128 f1 f2.
Definition cmp (c:comparison) (f1 f2: float32) : bool := (**r comparison *)
cmp_of_comparison c (compare f1 f2).
Definition ordered (f1 f2: float32) : bool :=
ordered_of_comparison (compare f1 f2).
(** Conversions *)
Definition of_double : float -> float32 := Float.to_single.
Definition to_double : float32 -> float := Float.of_single.
Definition to_int (f:float32): option int := (**r conversion to signed 32-bit int *)
option_map Int.repr (ZofB_range _ _ f Int.min_signed Int.max_signed).
Definition to_intu (f:float32): option int := (**r conversion to unsigned 32-bit int *)
option_map Int.repr (ZofB_range _ _ f 0 Int.max_unsigned).
Definition to_long (f:float32): option int64 := (**r conversion to signed 64-bit int *)
option_map Int64.repr (ZofB_range _ _ f Int64.min_signed Int64.max_signed).
Definition to_longu (f:float32): option int64 := (**r conversion to unsigned 64-bit int *)
option_map Int64.repr (ZofB_range _ _ f 0 Int64.max_unsigned).
Definition of_int (n:int): float32 := (**r conversion from signed 32-bit int to single-precision float *)
BofZ 24 128 __ __ (Int.signed n).
Definition of_intu (n:int): float32 := (**r conversion from unsigned 32-bit int to single-precision float *)
BofZ 24 128 __ __ (Int.unsigned n).
Definition of_long (n:int64): float32 := (**r conversion from signed 64-bit int to single-precision float *)
BofZ 24 128 __ __ (Int64.signed n).
Definition of_longu (n:int64): float32 := (**r conversion from unsigned 64-bit int to single-precision float *)
BofZ 24 128 __ __ (Int64.unsigned n).
Definition from_parsed (base:positive) (intPart:positive) (expPart:Z) : float32 :=
Bparse 24 128 __ __ base intPart expPart.
(** Conversions between floats and their concrete in-memory representation as a sequence of 32 bits. *)
Definition to_bits (f: float32) : int := Int.repr (bits_of_b32 f).
Definition of_bits (b: int): float32 := b32_of_bits (Int.unsigned b).
(** ** Properties *)
(** Commutativity properties of addition and multiplication. *)

(* Specifications: *)
Theorem add_commut:
forall x y, is_nan _ _ x = false \/ is_nan _ _ y = false -> add x y = add y x.
Theorem mul_commut:
forall x y, is_nan _ _ x = false \/ is_nan _ _ y = false -> mul x y = mul y x.