Module Gg.Float

Floating point number utilities.

This module extends the OCaml Stdlib.Float module. It also provides this quick recall on OCaml's floating point representation.

Note. Functions taking NaNs return NaNs unless otherwise specified.

Warning. This module existed before Stdlib.Float was introduced in OCaml 4.07.0. Since Gg 1.0.0, the module now includes Stdlib.Float and some values initially provided by Gg are now provided by Stdlib.Float, see the release notes of the package for a precise account of the changes.

Stdlib.Float

include module type of Stdlib.Float
val zero : float
val one : float
val minus_one : float
val neg : float -> float
val add : float -> float -> float
val sub : float -> float -> float
val mul : float -> float -> float
val div : float -> float -> float
val fma : float -> float -> float -> float
val rem : float -> float -> float
val succ : float -> float
val pred : float -> float
val abs : float -> float
val infinity : float
val neg_infinity : float
val nan : float
val pi : float
val max_float : float
val min_float : float
val epsilon : float
val is_finite : float -> bool
val is_infinite : float -> bool
val is_nan : float -> bool
val is_integer : float -> bool
val of_int : int -> float
val to_int : float -> int
val of_string : string -> float
val of_string_opt : string -> float option
val to_string : float -> string
type fpclass = Stdlib.fpclass =
  1. | FP_normal
  2. | FP_subnormal
  3. | FP_zero
  4. | FP_infinite
  5. | FP_nan
val classify_float : float -> fpclass
val pow : float -> float -> float
val sqrt : float -> float
val cbrt : float -> float
val exp : float -> float
val exp2 : float -> float
val log : float -> float
val log10 : float -> float
val log2 : float -> float
val expm1 : float -> float
val log1p : float -> float
val cos : float -> float
val sin : float -> float
val tan : float -> float
val acos : float -> float
val asin : float -> float
val atan : float -> float
val atan2 : float -> float -> float
val hypot : float -> float -> float
val cosh : float -> float
val sinh : float -> float
val tanh : float -> float
val acosh : float -> float
val asinh : float -> float
val atanh : float -> float
val erf : float -> float
val erfc : float -> float
val trunc : float -> float
val round : float -> float
val ceil : float -> float
val floor : float -> float
val next_after : float -> float -> float
val copy_sign : float -> float -> float
val sign_bit : float -> bool
val frexp : float -> float * int
val ldexp : float -> int -> float
val modf : float -> float * float
type t = float
val compare : t -> t -> int
val equal : t -> t -> bool
val min : t -> t -> t
val max : float -> float -> float
val min_max : float -> float -> float * float
val min_num : t -> t -> t
val max_num : t -> t -> t
val min_max_num : float -> float -> float * float
val hash : t -> int
module Array : sig ... end
module ArrayLabels : sig ... end

Constants

val e : float

The constant e.

val two_pi : float

2 *. pi, two times pi.

val pi_div_2 : float

pi /. 2.

val pi_div_4 : float

pi /. 4.

val inv_pi : float

1 /. pi.

val max_sub_float : float

The greatest positive subnormal floating point number.

val min_sub_float : float

The smallest positive subnormal floating point number.

val max_frac_float : float

The greatest positive floating point number with a fractional part (the float before 252). Any number outside [-max_frac_float;max_frac_float] is an integer.

val max_int_arith : float

The greatest positive floating point number (253) such that any integer in the range [-max_int_arith;max_int_arith] is represented exactly. Integer arithmetic can be performed exactly in this interval.

Angles

val deg_of_rad : float -> float

deg_of_rad r is r radians in degrees.

val rad_of_deg : float -> float

rad_of_deg d is d degrees in radians.

val wrap_angle : float -> float

wrap_angle r is the angle r in the interval [-pi;pi[.

Random

val random : ?min:float -> len:float -> unit -> float

random min len () is a random float in the interval [min;min+len] (min defaults to 0.). Uses the standard library's default Random state for the generation.

Warning. The float generated by a given state may change in future versions of the library.

val srandom : Stdlib.Random.State.t -> ?min:float -> len:float -> unit -> float

srandom state min len () is like random but uses state for the generation.

Warning. The float generated by a given state may change in future versions of the library.

Intervals

val mix : float -> float -> float -> float

mix x y t is the linear interpolation x +. t *. (y -. x).

val step : float -> float -> float

step edge x is 0. if x < edge and 1. otherwise. The result is undefined on NaNs.

val smooth_step : float -> float -> float -> float

smooth_step e0 e1 x is 0. if x <= e0, 1. if x >= e1 and cubic hermite interpolation between 0. and 1. otherwise. The result is undefined on NaNs.

val clamp : min:float -> max:float -> float -> float

clamp min max x is min if x < min, max if x > max and x otherwise. The result is undefined on NaNs and if min > max.

val remap : x0:float -> x1:float -> y0:float -> y1:float -> float -> float

remap x0 x1 y0 y1 v applies to v the affine transform that maps x0 to y0 and x1 to y1. If the transform is undefined (x0 = x1 and y0 <> y1) the function returns y0 for any v.

val seg_inter : u0:float -> u1:float -> v0:float -> v1:float -> [ `None | `Pt of float | `Seg of float * float ]

seg_inter ~u0 ~u1 ~v0 ~v1 is the intersection between segments (intervals) [u0;u1] (with u0 <= u1) and [v0;v1] (with v0 <= v1). This is:

  • `None if the intervals are disjoint.
  • `Pt x if they intersect on the single point x.
  • `Seg (x0, x1) if they intersect on the interval [x0;x1] (with x0 < x1).

Note. Terminology uses segments rather intervals to match P2.seg_inter.

Rounding and truncating

val int_of_round : float -> int

int_of_round x is truncate (round v). The result is undefined on NaNs and infinities.

val round_dfrac : int -> float -> float

round_dfrac d x rounds x to the dth decimal fractional digit. Ties are rounded towards positive infinity. If x is an infinity, returns x. The result is only defined for 0 <= d <= 16.

val round_dsig : int -> float -> float

round_dsig d x rounds the normalized decimal significand of x to the dth decimal fractional digit. Ties are rounded towards positive infinity. The result is NaN on infinities. The result only defined for 0 <= d <= 16.

Warning. The current implementation overflows on large x and d.

val round_zero : eps:float -> float -> float

round_zero eps x is 0. if abs_float x < eps and x otherwise. The result is undefined if eps is NaN.

val chop : eps:float -> float -> float

chop eps x is round x if abs_float (x -. round x) < eps and x otherwise. The result is undefined if eps is NaN.

NaNs

val nan_with_payload : int -> float

nan_with_payload payload is a NaN whose 51 lower significand bits are defined by the 51 lower (or less, as int allows) bits of payload.

val nan_payload : float -> int

nan_payload x is the 51 lower significand bits (or less, as int allows) of the NaN x.

Raises Invalid_argument if x is not a NaN.

Predicates and comparisons

val sign : float -> float

sign x is 1. if x > 0., 0. if x = 0., -1. if x < 0.

val is_zero : eps:float -> float -> bool

is_zero eps x is true if abs_float x < eps and false otherwise. The result is undefined if eps is NaN.

val equal_tol : eps:float -> float -> float -> bool

equal_tol eps x y is true iff |x - y| <= eps * max (1,|x|,|y|). On special values the function behaves like compare x y = 0. The condition turns into an absolute tolerance test for small magnitudes and a relative tolerance test for large magnitudes.

val compare_tol : eps:float -> float -> float -> int

compare_tol ~eps x y is 0 iff equal_tol ~eps x y is true and Stdlib.compare x y otherwise.

Formatting

val pp : Stdlib.Format.formatter -> float -> unit

pp ppf x formats a lossless textual representation of x on ppf using "%h". Since 1.0.0, before this was the slower legacy_pp whose output differs on the representation of nan, infinities, or zeros.

Deprecated

val fmax : float -> float -> float

Deprecated use max_num.

  • deprecated Use Float.max_num instead.
val fmin : float -> float -> float

Deprecated use min_num.

  • deprecated Use Float.min_num instead.
val is_inf : float -> bool

Deprecated use is_infinite.

  • deprecated Use Float.is_infinite instead.
val is_int : float -> bool

Deprecated use is_integer.

  • deprecated Use Float.is_integer instead.
val legacy_pp : Stdlib.Format.formatter -> float -> unit

Deprecated use pp.

pp_legacy ppf x prints a lossless textual representation of x on ppf.

  • Normals are represented by "[-]0x1.<f>p<e>" where <f> is the significand bits in hexadecimal and <e> the unbiased exponent in decimal.
  • Subnormals are represented by "[-]0x0.<f>p-1022" where <f> is the significand bits in hexadecimal.
  • NaNs are represented by "[-]nan(0x<p>)" where <p> is the payload in hexadecimal.
  • Infinities and zeroes are represented by "[-]inf" and "[-]0.".

This format should be compatible with recent implementations of strtod and hence with float_of_string (but negative NaNs seem to be problematic to get back).

  • deprecated Use Float.pp instead (some values may render differently).

Quick recall on OCaml's floats

An OCaml float is an IEEE-754 64 bit double precision binary floating point number. The 64 bits are laid out as follows :

+----------------+-----------------------+-------------------------+
| sign s (1 bit) | exponent e (11 bits)  | significand t (52 bits) |
+----------------+-----------------------+-------------------------+
               63|62                   52|51                      0|

The value represented depends on s, e and t :

sign   exponent       significand   value represented           meaning
-------------------------------------------------------------------------
s      0              0             -1^s * 0                    zero
s      0              t <> 0        -1^s * 0.t * 2^-1022        subnormal
s      0 < e < 2047   f             -1^s * 1.t * 2^(e - 1023)   normal
s      2047           0             -1^s * infinity             infinity
s      2047           t <> 0        NaN                         not a number

There are two zeros, a positive and a negative one but both are deemed equal by = and Stdlib.compare. A NaN is never equal (=) to itself or to another NaN however Stdlib.compare asserts any NaN to be equal to itself and to any other NaN.

The bit layout of a float can be converted to an int64 and back using Int64.bits_of_float and Int64.float_of_bits.

The bit 51 of a NaN is used to distinguish between quiet (bit set) and signaling NaNs (bit cleared); the remaining 51 lower bits of the significand are the NaN's payload which can be used to store diagnostic information. These features don't seem to used in OCaml.

The significand of a floating point number is made of 53 binary digits (don't forget the implicit digit), this corresponds to log10(253) ~ 16 decimal digits.

Only float values in the interval ]-252;252[ may have a fractional part. Float.max_frac_float is the greatest positive float with a fractional part.

Any integer value in the interval [-253;253] can be represented exactly by a float value. Integer arithmetic performed in this interval is exact. Float.max_int_arith is 253.