Source file SpecFloat.ml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
# 1 "extracted/SpecFloat.ml"
open BinInt
open Datatypes
open Zpower

type spec_float =
| S754_zero of bool
| S754_infinity of bool
| S754_nan
| S754_finite of bool * Farith_Big.big_int * Farith_Big.big_int

(** val emin :
    Farith_Big.big_int -> Farith_Big.big_int -> Farith_Big.big_int **)

let emin prec emax =
  Farith_Big.sub
    (Farith_Big.sub (Farith_Big.succ_double Farith_Big.one) emax) prec

(** val fexp :
    Farith_Big.big_int -> Farith_Big.big_int -> Farith_Big.big_int ->
    Farith_Big.big_int **)

let fexp prec emax e =
  Farith_Big.max (Farith_Big.sub e prec) (emin prec emax)

(** val digits2_pos : Farith_Big.big_int -> Farith_Big.big_int **)

let rec digits2_pos n =
  Farith_Big.positive_case
    (fun p -> Farith_Big.succ (digits2_pos p))
    (fun p -> Farith_Big.succ (digits2_pos p))
    (fun _ -> Farith_Big.one)
    n

(** val coq_Zdigits2 : Farith_Big.big_int -> Farith_Big.big_int **)

let coq_Zdigits2 n =
  Farith_Big.z_case
    (fun _ -> n)
    (fun p -> (digits2_pos p))
    (fun p -> (digits2_pos p))
    n

(** val iter_pos : ('a1 -> 'a1) -> Farith_Big.big_int -> 'a1 -> 'a1 **)

let rec iter_pos f n x =
  Farith_Big.positive_case
    (fun n' -> iter_pos f n' (iter_pos f n' (f x)))
    (fun n' -> iter_pos f n' (iter_pos f n' x))
    (fun _ -> f x)
    n

type location =
| Coq_loc_Exact
| Coq_loc_Inexact of comparison

type shr_record = { shr_m : Farith_Big.big_int; shr_r : bool; shr_s : bool }

(** val shr_1 : shr_record -> shr_record **)

let shr_1 mrs =
  let { shr_m = m; shr_r = r; shr_s = s } = mrs in
  let s0 = (||) r s in
  (Farith_Big.z_case
     (fun _ -> { shr_m = Farith_Big.zero; shr_r = false; shr_s =
     s0 })
     (fun p0 ->
     Farith_Big.positive_case
       (fun p -> { shr_m = p; shr_r = true; shr_s = s0 })
       (fun p -> { shr_m = p; shr_r = false; shr_s = s0 })
       (fun _ -> { shr_m = Farith_Big.zero; shr_r = true; shr_s = s0 })
       p0)
     (fun p0 ->
     Farith_Big.positive_case
       (fun p -> { shr_m = (Farith_Big.opp p); shr_r = true; shr_s =
       s0 })
       (fun p -> { shr_m = (Farith_Big.opp p); shr_r = false; shr_s =
       s0 })
       (fun _ -> { shr_m = Farith_Big.zero; shr_r = true; shr_s = s0 })
       p0)
     m)

(** val loc_of_shr_record : shr_record -> location **)

let loc_of_shr_record mrs =
  let { shr_m = _; shr_r = shr_r0; shr_s = shr_s0 } = mrs in
  if shr_r0
  then if shr_s0 then Coq_loc_Inexact Gt else Coq_loc_Inexact Eq
  else if shr_s0 then Coq_loc_Inexact Lt else Coq_loc_Exact

(** val shr_record_of_loc : Farith_Big.big_int -> location -> shr_record **)

let shr_record_of_loc m = function
| Coq_loc_Exact -> { shr_m = m; shr_r = false; shr_s = false }
| Coq_loc_Inexact c ->
  (match c with
   | Eq -> { shr_m = m; shr_r = true; shr_s = false }
   | Lt -> { shr_m = m; shr_r = false; shr_s = true }
   | Gt -> { shr_m = m; shr_r = true; shr_s = true })

(** val shr :
    shr_record -> Farith_Big.big_int -> Farith_Big.big_int ->
    shr_record * Farith_Big.big_int **)

let shr mrs e n =
  Farith_Big.z_case
    (fun _ -> (mrs, e))
    (fun p -> ((iter_pos shr_1 p mrs), (Farith_Big.add e n)))
    (fun _ -> (mrs, e))
    n

(** val shr_fexp :
    Farith_Big.big_int -> Farith_Big.big_int -> Farith_Big.big_int ->
    Farith_Big.big_int -> location -> shr_record * Farith_Big.big_int **)

let shr_fexp prec emax m e l =
  shr (shr_record_of_loc m l) e
    (Farith_Big.sub (fexp prec emax (Farith_Big.add (coq_Zdigits2 m) e)) e)

(** val shl_align :
    Farith_Big.big_int -> Farith_Big.big_int -> Farith_Big.big_int ->
    Farith_Big.big_int * Farith_Big.big_int **)

let shl_align mx ex ex' =
  Farith_Big.z_case
    (fun _ -> (mx, ex))
    (fun _ -> (mx, ex))
    (fun d -> ((shift_pos d mx), ex'))
    (Farith_Big.sub ex' ex)

(** val coq_SFcompare : spec_float -> spec_float -> comparison option **)

let coq_SFcompare f1 f2 =
  match f1 with
  | S754_zero _ ->
    (match f2 with
     | S754_zero _ -> Some Eq
     | S754_infinity s -> Some (if s then Gt else Lt)
     | S754_nan -> None
     | S754_finite (s, _, _) -> Some (if s then Gt else Lt))
  | S754_infinity s ->
    (match f2 with
     | S754_infinity s0 ->
       Some (if s then if s0 then Eq else Lt else if s0 then Gt else Eq)
     | S754_nan -> None
     | _ -> Some (if s then Lt else Gt))
  | S754_nan -> None
  | S754_finite (s1, m1, e1) ->
    (match f2 with
     | S754_zero _ -> Some (if s1 then Lt else Gt)
     | S754_infinity s -> Some (if s then Gt else Lt)
     | S754_nan -> None
     | S754_finite (s2, m2, e2) ->
       Some
         (if s1
          then if s2
               then (match (Farith_Big.compare_case Eq Lt Gt) e1 e2 with
                     | Eq ->
                       coq_CompOpp
                         ((fun c x y -> Farith_Big.compare_case c Lt Gt x y)
                           Eq m1 m2)
                     | Lt -> Gt
                     | Gt -> Lt)
               else Lt
          else if s2
               then Gt
               else (match (Farith_Big.compare_case Eq Lt Gt) e1 e2 with
                     | Eq ->
                       (fun c x y -> Farith_Big.compare_case c Lt Gt x y) Eq
                         m1 m2
                     | x -> x)))

(** val coq_SFeqb : spec_float -> spec_float -> bool **)

let coq_SFeqb f1 f2 =
  match coq_SFcompare f1 f2 with
  | Some c -> (match c with
               | Eq -> true
               | _ -> false)
  | None -> false

(** val coq_SFltb : spec_float -> spec_float -> bool **)

let coq_SFltb f1 f2 =
  match coq_SFcompare f1 f2 with
  | Some c -> (match c with
               | Lt -> true
               | _ -> false)
  | None -> false

(** val coq_SFleb : spec_float -> spec_float -> bool **)

let coq_SFleb f1 f2 =
  match coq_SFcompare f1 f2 with
  | Some c -> (match c with
               | Gt -> false
               | _ -> true)
  | None -> false

(** val cond_Zopp : bool -> Farith_Big.big_int -> Farith_Big.big_int **)

let cond_Zopp b m =
  if b then Farith_Big.opp m else m

(** val new_location_even :
    Farith_Big.big_int -> Farith_Big.big_int -> location **)

let new_location_even nb_steps k =
  if Farith_Big.eq k Farith_Big.zero
  then Coq_loc_Exact
  else Coq_loc_Inexact
         ((Farith_Big.compare_case Eq Lt Gt)
           (Farith_Big.mult (Farith_Big.double Farith_Big.one) k) nb_steps)

(** val new_location_odd :
    Farith_Big.big_int -> Farith_Big.big_int -> location **)

let new_location_odd nb_steps k =
  if Farith_Big.eq k Farith_Big.zero
  then Coq_loc_Exact
  else Coq_loc_Inexact
         (match (Farith_Big.compare_case Eq Lt Gt)
                  (Farith_Big.add
                    (Farith_Big.mult (Farith_Big.double Farith_Big.one) k)
                    Farith_Big.one) nb_steps with
          | Eq -> Lt
          | x -> x)

(** val new_location :
    Farith_Big.big_int -> Farith_Big.big_int -> location **)

let new_location nb_steps =
  if Z.even nb_steps
  then new_location_even nb_steps
  else new_location_odd nb_steps

(** val coq_SFdiv_core_binary :
    Farith_Big.big_int -> Farith_Big.big_int -> Farith_Big.big_int ->
    Farith_Big.big_int -> Farith_Big.big_int -> Farith_Big.big_int ->
    (Farith_Big.big_int * Farith_Big.big_int) * location **)

let coq_SFdiv_core_binary prec emax m1 e1 m2 e2 =
  let d1 = coq_Zdigits2 m1 in
  let d2 = coq_Zdigits2 m2 in
  let e' =
    Farith_Big.min
      (fexp prec emax
        (Farith_Big.sub (Farith_Big.add d1 e1) (Farith_Big.add d2 e2)))
      (Farith_Big.sub e1 e2)
  in
  let s = Farith_Big.sub (Farith_Big.sub e1 e2) e' in
  let m' =
    Farith_Big.z_case
      (fun _ -> m1)
      (fun _ -> Farith_Big.shiftl m1 s)
      (fun _ -> Farith_Big.zero)
      s
  in
  let (q, r) = Farith_Big.div_mod_floor m' m2 in
  ((q, e'), (new_location m2 r))

(** val coq_SFsqrt_core_binary :
    Farith_Big.big_int -> Farith_Big.big_int -> Farith_Big.big_int ->
    Farith_Big.big_int -> (Farith_Big.big_int * Farith_Big.big_int) * location **)

let coq_SFsqrt_core_binary prec emax m e =
  let d = coq_Zdigits2 m in
  let e' =
    Farith_Big.min
      (fexp prec emax
        (Farith_Big.div2_floor
          (Farith_Big.add (Farith_Big.add d e) Farith_Big.one)))
      (Farith_Big.div2_floor e)
  in
  let s =
    Farith_Big.sub e (Farith_Big.mult (Farith_Big.double Farith_Big.one) e')
  in
  let m' =
    Farith_Big.z_case
      (fun _ -> m)
      (fun _ -> Farith_Big.shiftl m s)
      (fun _ -> Farith_Big.zero)
      s
  in
  let (q, r) = Farith_Big.Z.sqrt_rem m' in
  let l =
    if Farith_Big.eq r Farith_Big.zero
    then Coq_loc_Exact
    else Coq_loc_Inexact (if Farith_Big.le r q then Lt else Gt)
  in
  ((q, e'), l)