|
| 1 | +(**************************************************************************) |
| 2 | +(* *) |
| 3 | +(* OCaml *) |
| 4 | +(* *) |
| 5 | +(* Xavier Leroy, projet Cristal, INRIA Rocquencourt *) |
| 6 | +(* Nicolas Ojeda Bar, LexiFi *) |
| 7 | +(* *) |
| 8 | +(* Copyright 2018 Institut National de Recherche en Informatique et *) |
| 9 | +(* en Automatique. *) |
| 10 | +(* *) |
| 11 | +(* All rights reserved. This file is distributed under the terms of *) |
| 12 | +(* the GNU Lesser General Public License version 2.1, with the *) |
| 13 | +(* special exception on linking described in the file LICENSE. *) |
| 14 | +(* *) |
| 15 | +(**************************************************************************) |
| 16 | + |
| 17 | +[@@@ocaml.flambda_o3] |
| 18 | + |
| 19 | +type t = float32 |
| 20 | + |
| 21 | +external float32_of_bits : int32 -> float32 |
| 22 | + = "caml_float32_of_bits_bytecode" "caml_float32_of_bits" |
| 23 | + [@@unboxed] [@@noalloc] |
| 24 | + |
| 25 | +external neg : (float32[@local_opt]) -> (float32[@local_opt]) = "%negfloat32" |
| 26 | + |
| 27 | +external add : |
| 28 | + (float32[@local_opt]) -> (float32[@local_opt]) -> (float32[@local_opt]) |
| 29 | + = "%addfloat32" |
| 30 | + |
| 31 | +external sub : |
| 32 | + (float32[@local_opt]) -> (float32[@local_opt]) -> (float32[@local_opt]) |
| 33 | + = "%subfloat32" |
| 34 | + |
| 35 | +external mul : |
| 36 | + (float32[@local_opt]) -> (float32[@local_opt]) -> (float32[@local_opt]) |
| 37 | + = "%mulfloat32" |
| 38 | + |
| 39 | +external div : |
| 40 | + (float32[@local_opt]) -> (float32[@local_opt]) -> (float32[@local_opt]) |
| 41 | + = "%divfloat32" |
| 42 | + |
| 43 | +external pow : float32 -> float32 -> float32 |
| 44 | + = "caml_power_float32_bytecode" "powf" |
| 45 | + [@@unboxed] [@@noalloc] |
| 46 | + |
| 47 | +module Operators = struct |
| 48 | + external ( ~-. ) : (float32[@local_opt]) -> (float32[@local_opt]) |
| 49 | + = "%negfloat32" |
| 50 | + |
| 51 | + external ( +. ) : |
| 52 | + (float32[@local_opt]) -> (float32[@local_opt]) -> (float32[@local_opt]) |
| 53 | + = "%addfloat32" |
| 54 | + |
| 55 | + external ( -. ) : |
| 56 | + (float32[@local_opt]) -> (float32[@local_opt]) -> (float32[@local_opt]) |
| 57 | + = "%subfloat32" |
| 58 | + |
| 59 | + external ( *. ) : |
| 60 | + (float32[@local_opt]) -> (float32[@local_opt]) -> (float32[@local_opt]) |
| 61 | + = "%mulfloat32" |
| 62 | + |
| 63 | + external ( /. ) : |
| 64 | + (float32[@local_opt]) -> (float32[@local_opt]) -> (float32[@local_opt]) |
| 65 | + = "%divfloat32" |
| 66 | + |
| 67 | + external ( ** ) : float32 -> float32 -> float32 |
| 68 | + = "caml_power_float32_bytecode" "powf" |
| 69 | + [@@unboxed] [@@noalloc] |
| 70 | +end |
| 71 | + |
| 72 | +external fma : float32 -> float32 -> float32 -> float32 |
| 73 | + = "caml_fma_float32_bytecode" "fmaf" |
| 74 | + [@@unboxed] [@@noalloc] |
| 75 | + |
| 76 | +external rem : float32 -> float32 -> float32 |
| 77 | + = "caml_fmod_float32_bytecode" "fmodf" |
| 78 | + [@@unboxed] [@@noalloc] |
| 79 | + |
| 80 | +external abs : (float32[@local_opt]) -> (float32[@local_opt]) = "%absfloat32" |
| 81 | + |
| 82 | +let zero = 0.s |
| 83 | +let one = 1.s |
| 84 | +let minus_one = -1.s |
| 85 | +let infinity = float32_of_bits 0x7f800000l |
| 86 | +let neg_infinity = float32_of_bits 0xff800000l |
| 87 | +let nan = float32_of_bits 0x7f800001l |
| 88 | +let is_finite (x : float32) = sub x x = 0.s |
| 89 | +let is_infinite (x : float32) = div 1.s x = 0.s |
| 90 | +let is_nan (x : float32) = x <> x |
| 91 | +let pi = 0x1.921fb6p+1s |
| 92 | +let max_float = float32_of_bits 0x7f7fffffl |
| 93 | +let min_float = float32_of_bits 0x00800000l |
| 94 | +let epsilon = float32_of_bits 0x34000000l |
| 95 | + |
| 96 | +external of_int : int -> float32 = "%float32ofint" |
| 97 | +external to_int : (float32[@local_opt]) -> int = "%intoffloat32" |
| 98 | +external of_float : (float[@local_opt]) -> float32 = "%float32offloat" |
| 99 | +external to_float : (float32[@local_opt]) -> float = "%floatoffloat32" |
| 100 | + |
| 101 | +external of_bits : (int32[@local_opt]) -> float32 |
| 102 | + = "caml_float32_of_bits_bytecode" "caml_float32_of_bits" |
| 103 | + [@@unboxed] [@@noalloc] |
| 104 | + |
| 105 | +external to_bits : (float32[@local_opt]) -> int32 |
| 106 | + = "caml_float32_to_bits_bytecode" "caml_float32_to_bits" |
| 107 | + [@@unboxed] [@@noalloc] |
| 108 | + |
| 109 | +external of_string : string -> float32 = "caml_float32_of_string" |
| 110 | + |
| 111 | +let of_string_opt s = try Some (of_string s) with Failure _ -> None |
| 112 | + |
| 113 | +external format : string -> float32 -> string = "caml_format_float32" |
| 114 | + |
| 115 | +let to_string f = Stdlib.valid_float_lexem (format "%.9g" f) |
| 116 | + |
| 117 | +type fpclass = Stdlib.fpclass = |
| 118 | + | FP_normal |
| 119 | + | FP_subnormal |
| 120 | + | FP_zero |
| 121 | + | FP_infinite |
| 122 | + | FP_nan |
| 123 | + |
| 124 | +external classify_float : (float32[@unboxed]) -> fpclass |
| 125 | + = "caml_classify_float32_bytecode" "caml_classify_float32" |
| 126 | + [@@noalloc] |
| 127 | + |
| 128 | +external sqrt : float32 -> float32 = "caml_sqrt_float32_bytecode" "sqrtf" |
| 129 | + [@@unboxed] [@@noalloc] |
| 130 | + |
| 131 | +external cbrt : float32 -> float32 = "caml_cbrt_float32_bytecode" "cbrtf" |
| 132 | + [@@unboxed] [@@noalloc] |
| 133 | + |
| 134 | +external exp : float32 -> float32 = "caml_exp_float32_bytecode" "expf" |
| 135 | + [@@unboxed] [@@noalloc] |
| 136 | + |
| 137 | +external exp2 : float32 -> float32 = "caml_exp2_float32_bytecode" "exp2f" |
| 138 | + [@@unboxed] [@@noalloc] |
| 139 | + |
| 140 | +external log : float32 -> float32 = "caml_log_float32_bytecode" "logf" |
| 141 | + [@@unboxed] [@@noalloc] |
| 142 | + |
| 143 | +external log10 : float32 -> float32 = "caml_log10_float32_bytecode" "log10f" |
| 144 | + [@@unboxed] [@@noalloc] |
| 145 | + |
| 146 | +external log2 : float32 -> float32 = "caml_log2_float32_bytecode" "log2f" |
| 147 | + [@@unboxed] [@@noalloc] |
| 148 | + |
| 149 | +external expm1 : float32 -> float32 = "caml_expm1_float32_bytecode" "expm1f" |
| 150 | + [@@unboxed] [@@noalloc] |
| 151 | + |
| 152 | +external log1p : float32 -> float32 = "caml_log1p_float32_bytecode" "log1pf" |
| 153 | + [@@unboxed] [@@noalloc] |
| 154 | + |
| 155 | +external cos : float32 -> float32 = "caml_cos_float32_bytecode" "cosf" |
| 156 | + [@@unboxed] [@@noalloc] |
| 157 | + |
| 158 | +external sin : float32 -> float32 = "caml_sin_float32_bytecode" "sinf" |
| 159 | + [@@unboxed] [@@noalloc] |
| 160 | + |
| 161 | +external tan : float32 -> float32 = "caml_tan_float32_bytecode" "tanf" |
| 162 | + [@@unboxed] [@@noalloc] |
| 163 | + |
| 164 | +external acos : float32 -> float32 = "caml_acos_float32_bytecode" "acosf" |
| 165 | + [@@unboxed] [@@noalloc] |
| 166 | + |
| 167 | +external asin : float32 -> float32 = "caml_asin_float32_bytecode" "asinf" |
| 168 | + [@@unboxed] [@@noalloc] |
| 169 | + |
| 170 | +external atan : float32 -> float32 = "caml_atan_float32_bytecode" "atanf" |
| 171 | + [@@unboxed] [@@noalloc] |
| 172 | + |
| 173 | +external atan2 : float32 -> float32 -> float32 |
| 174 | + = "caml_atan2_float32_bytecode" "atan2f" |
| 175 | + [@@unboxed] [@@noalloc] |
| 176 | + |
| 177 | +external hypot : float32 -> float32 -> float32 |
| 178 | + = "caml_hypot_float32_bytecode" "hypotf" |
| 179 | + [@@unboxed] [@@noalloc] |
| 180 | + |
| 181 | +external cosh : float32 -> float32 = "caml_cosh_float32_bytecode" "coshf" |
| 182 | + [@@unboxed] [@@noalloc] |
| 183 | + |
| 184 | +external sinh : float32 -> float32 = "caml_sinh_float32_bytecode" "sinhf" |
| 185 | + [@@unboxed] [@@noalloc] |
| 186 | + |
| 187 | +external tanh : float32 -> float32 = "caml_tanh_float32_bytecode" "tanhf" |
| 188 | + [@@unboxed] [@@noalloc] |
| 189 | + |
| 190 | +external acosh : float32 -> float32 = "caml_acosh_float32_bytecode" "acoshf" |
| 191 | + [@@unboxed] [@@noalloc] |
| 192 | + |
| 193 | +external asinh : float32 -> float32 = "caml_asinh_float32_bytecode" "asinhf" |
| 194 | + [@@unboxed] [@@noalloc] |
| 195 | + |
| 196 | +external atanh : float32 -> float32 = "caml_atanh_float32_bytecode" "atanhf" |
| 197 | + [@@unboxed] [@@noalloc] |
| 198 | + |
| 199 | +external erf : float32 -> float32 = "caml_erf_float32_bytecode" "erff" |
| 200 | + [@@unboxed] [@@noalloc] |
| 201 | + |
| 202 | +external erfc : float32 -> float32 = "caml_erfc_float32_bytecode" "erfcf" |
| 203 | + [@@unboxed] [@@noalloc] |
| 204 | + |
| 205 | +external trunc : float32 -> float32 = "caml_trunc_float32_bytecode" "truncf" |
| 206 | + [@@unboxed] [@@noalloc] |
| 207 | + |
| 208 | +external round : float32 -> float32 = "caml_round_float32_bytecode" "roundf" |
| 209 | + [@@unboxed] [@@noalloc] |
| 210 | + |
| 211 | +external ceil : float32 -> float32 = "caml_ceil_float32_bytecode" "ceilf" |
| 212 | + [@@unboxed] [@@noalloc] |
| 213 | + |
| 214 | +external floor : float32 -> float32 = "caml_floor_float32_bytecode" "floorf" |
| 215 | + [@@unboxed] [@@noalloc] |
| 216 | + |
| 217 | +let is_integer x = x = trunc x && is_finite x |
| 218 | + |
| 219 | +external next_after : float32 -> float32 -> float32 |
| 220 | + = "caml_nextafter_float32_bytecode" "nextafterf" |
| 221 | + [@@unboxed] [@@noalloc] |
| 222 | + |
| 223 | +let succ x = next_after x infinity |
| 224 | +let pred x = next_after x neg_infinity |
| 225 | + |
| 226 | +external copy_sign : float32 -> float32 -> float32 |
| 227 | + = "caml_copysign_float32_bytecode" "copysignf" |
| 228 | + [@@unboxed] [@@noalloc] |
| 229 | + |
| 230 | +external sign_bit : (float32[@unboxed]) -> bool |
| 231 | + = "caml_signbit_float32_bytecode" "caml_signbit_float32" |
| 232 | + [@@noalloc] |
| 233 | + |
| 234 | +external frexp : float32 -> float32 * int = "caml_frexp_float32" |
| 235 | + |
| 236 | +external ldexp : (float32[@unboxed]) -> (int[@untagged]) -> (float32[@unboxed]) |
| 237 | + = "caml_ldexp_float32_bytecode" "caml_ldexp_float32" |
| 238 | + [@@noalloc] |
| 239 | + |
| 240 | +external modf : float32 -> float32 * float32 = "caml_modf_float32" |
| 241 | +external compare : float32 -> float32 -> int = "%compare" |
| 242 | + |
| 243 | +let equal x y = compare x y = 0 |
| 244 | + |
| 245 | +let[@inline] min (x : float32) (y : float32) = |
| 246 | + if y > x || ((not (sign_bit y)) && sign_bit x) then if is_nan y then y else x |
| 247 | + else if is_nan x then x |
| 248 | + else y |
| 249 | + |
| 250 | +let[@inline] max (x : float32) (y : float32) = |
| 251 | + if y > x || ((not (sign_bit y)) && sign_bit x) then if is_nan x then x else y |
| 252 | + else if is_nan y then y |
| 253 | + else x |
| 254 | + |
| 255 | +let[@inline] min_max (x : float32) (y : float32) = |
| 256 | + if is_nan x || is_nan y then (nan, nan) |
| 257 | + else if y > x || ((not (sign_bit y)) && sign_bit x) then (x, y) |
| 258 | + else (y, x) |
| 259 | + |
| 260 | +let[@inline] min_num (x : float32) (y : float32) = |
| 261 | + if y > x || ((not (sign_bit y)) && sign_bit x) then if is_nan x then y else x |
| 262 | + else if is_nan y then x |
| 263 | + else y |
| 264 | + |
| 265 | +let[@inline] max_num (x : float32) (y : float32) = |
| 266 | + if y > x || ((not (sign_bit y)) && sign_bit x) then if is_nan y then x else y |
| 267 | + else if is_nan x then y |
| 268 | + else x |
| 269 | + |
| 270 | +let[@inline] min_max_num (x : float32) (y : float32) = |
| 271 | + if is_nan x then (y, y) |
| 272 | + else if is_nan y then (x, x) |
| 273 | + else if y > x || ((not (sign_bit y)) && sign_bit x) then (x, y) |
| 274 | + else (y, x) |
| 275 | + |
| 276 | +external seeded_hash_param : int -> int -> int -> 'a -> int = "caml_hash_exn" |
| 277 | + [@@noalloc] |
| 278 | + |
| 279 | +let seeded_hash seed x = seeded_hash_param 10 100 seed x |
| 280 | +let hash x = seeded_hash_param 10 100 0 x |
0 commit comments