aboutsummaryrefslogtreecommitdiff
path: root/kernel/float64.ml
diff options
context:
space:
mode:
authorPierre Roux2018-08-28 23:37:49 +0200
committerPierre Roux2019-11-01 10:20:39 +0100
commit5f1270242f71a0a1da7c868967e1071d28ed83fb (patch)
tree53b283bee4bd7a434854c675033b9dcd3d8fbb02 /kernel/float64.ml
parentd18b928154a48ff8d90aaff69eca7d6eb3dfa0ab (diff)
Add next_{up,down} primitive float functions
Diffstat (limited to 'kernel/float64.ml')
-rw-r--r--kernel/float64.ml18
1 files changed, 18 insertions, 0 deletions
diff --git a/kernel/float64.ml b/kernel/float64.ml
index 7b54fd0c4b..351661f44d 100644
--- a/kernel/float64.ml
+++ b/kernel/float64.ml
@@ -76,6 +76,24 @@ let frshiftexp f =
let ldshiftexp f e = ldexp f (snd (Uint63.to_int2 e) - eshift)
+let eta_float = ldexp 1. (-1074) (* smallest positive float (subnormal) *)
+
+let next_up f =
+ match classify_float f with
+ | FP_nan -> f
+ | FP_infinite -> if 0. < f then f else -.max_float
+ | FP_zero | FP_subnormal ->
+ let f = f +. eta_float in
+ if f = 0. then -0. else f (* or next_down may return -0. *)
+ | FP_normal ->
+ let f, e = frexp f in
+ if 0. < f || f <> -0.5 || e = -1021 then
+ ldexp (f +. epsilon_float /. 2.) e
+ else
+ ldexp (-0.5 +. epsilon_float /. 4.) e
+
+let next_down f = -.(next_up (-.f))
+
let equal f1 f2 =
match classify_float f1 with
| FP_normal | FP_subnormal | FP_infinite -> (f1 = f2)