(** Conversions from 64-bit integers to single-precision floats can be expressed as conversion to a double-precision float followed by a [Float32.of_double] conversion. To avoid double rounding when the integer is large (above [2^53]), a round to odd must be performed on the integer before conversion to double-precision float. *)

(* Specifications: *)
Lemma int_round_odd_plus:
forall p n, 0 <= p ->
int_round_odd n p = Z.land (Z.lor n (Z.land n (2^p-1) + (2^p-1))) (-(2^p)).
Lemma of_long_round_odd:
forall n conv_nan,
2^36 <= Z.abs n < 2^64 ->
BofZ 24 128 __ __ n = Bconv _ _ 24 128 __ __ conv_nan mode_NE (BofZ 53 1024 __ __ (Z.land (Z.lor n ((Z.land n 2047) + 2047)) (-2048))).
Theorem of_longu_double_1:
forall n,
Int64.unsigned n <= 2^53 ->
of_longu n = of_double (Float.of_longu n).
Theorem of_longu_double_2:
forall n,
2^36 <= Int64.unsigned n ->
of_longu n = of_double (Float.of_longu
(Int64.and (Int64.or n
(Int64.add (Int64.and n (Int64.repr 2047))
(Int64.repr 2047)))
(Int64.repr (-2048)))).
Theorem of_long_double_1:
forall n,
Z.abs (Int64.signed n) <= 2^53 ->
of_long n = of_double (Float.of_long n).
Theorem of_long_double_2:
forall n,
2^36 <= Z.abs (Int64.signed n) ->
of_long n = of_double (Float.of_long
(Int64.and (Int64.or n
(Int64.add (Int64.and n (Int64.repr 2047))
(Int64.repr 2047)))
(Int64.repr (-2048)))).
Lemma int_round_odd_plus:
forall p n, 0 <= p ->
int_round_odd n p = Z.land (Z.lor n (Z.land n (2^p-1) + (2^p-1))) (-(2^p)).
Lemma of_long_round_odd:
forall n conv_nan,
2^36 <= Z.abs n < 2^64 ->
BofZ 24 128 __ __ n = Bconv _ _ 24 128 __ __ conv_nan mode_NE (BofZ 53 1024 __ __ (Z.land (Z.lor n ((Z.land n 2047) + 2047)) (-2048))).
Theorem of_longu_double_1:
forall n,
Int64.unsigned n <= 2^53 ->
of_longu n = of_double (Float.of_longu n).
Theorem of_longu_double_2:
forall n,
2^36 <= Int64.unsigned n ->
of_longu n = of_double (Float.of_longu
(Int64.and (Int64.or n
(Int64.add (Int64.and n (Int64.repr 2047))
(Int64.repr 2047)))
(Int64.repr (-2048)))).
Theorem of_long_double_1:
forall n,
Z.abs (Int64.signed n) <= 2^53 ->
of_long n = of_double (Float.of_long n).
Theorem of_long_double_2:
forall n,
2^36 <= Z.abs (Int64.signed n) ->
of_long n = of_double (Float.of_long
(Int64.and (Int64.or n
(Int64.add (Int64.and n (Int64.repr 2047))
(Int64.repr 2047)))
(Int64.repr (-2048)))).