# Module Gg.Float

`module Float: `sig` .. `end``
Floating point number utilities.

This module defines a few useful constants, functions, predicates and comparisons on floating point numbers. The printers output a lossless textual representation of floats.

Quick recall on OCaml's floating point representation.

`type t = `float` `
The type for floating point numbers.

# Constants

`val e : `float``
The constant e.
`val pi : `float``
The constant pi.
`val two_pi : `float``
`2 *. 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.

# Functions

Note. If applicable, a function taking NaNs returns a NaN unless otherwise specified.

`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`[.
`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 : `Random.State.t -> ?min:float -> len:float -> unit -> float``
`srandom state min len ()` is like `Gg.Float.random` but uses `state` for the generation.

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

`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 fmax : `float -> float -> float``
`fmax x y` is `y` if `x < y` and `x` otherwise. If `x` or `y` is NaN returns the other argument. If both are NaNs returns NaN.
`val fmin : `float -> float -> float``
`fmin x y` is `x` if `x < y` and `y` otherwise. If `x` or `y` is NaN returns the other argument. If both are NaNs returns NaN.
`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 round : `float -> float``
`round x` is the integer nearest to `x`. Ties are rounded towards positive infinity. If `x` is an infinity, returns `x`.

Note. If the absolute magnitude of `x` is an integer strictly greater than `Gg.Float.max_frac_float`, `round x = x` may be `false`.

`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 `d`th 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 `d`th 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.
`val sign : `float -> float``
`sign x` is `1.` if `x > 0.`, `0.` if `x = 0.`, `-1.` if `x < 0.`
`val sign_bit : `float -> bool``
`sign_bit x` is `true` iff the sign bit is set in `x`.
`val succ : `float -> float``
`succ x` is the floating point value just after `x` towards positive infinity. Returns in particular :
• NaN on NaNs.
• `infinity` on `infinity`.
• `-max_float` on `neg_infinity`.
• `min_sub_float` on `0.` or `-0.`.

`val pred : `float -> float``
`pred x` is `-. succ (-.x)`, i.e. the floating point value before `x` towards negative infinity.
`val nan : `int -> float``
`nan 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 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 is_nan : `float -> bool``
`is_nan x` is `true` iff `x` is a NaN.
`val is_inf : `float -> bool``
`is_inf x` is `true` iff `x` is `infinity` or `neg_infinity`.
`val is_int : `float -> bool``
`is_int x` is `true` iff `x` is an integer.
`val equal : `float -> float -> bool``
`equal x y` is `x = y`.
`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 : `float -> float -> int``
`compare x y` is `Pervasives.compare x y`.
`val compare_tol : `eps:float -> float -> float -> int``
`compare_tol ~eps x y` is `0` iff `equal_tol ~eps x y` is `true` and `Pervasives.compare x y` otherwise.

# Printers

`val pp : `Format.formatter -> float -> unit``
`pp 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).

# Quick recall on OCaml's `float`s

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 `Pervasives.compare`. A NaN is never equal (=) to itself or to another NaN however `Pervasives.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 ]`-2`52;252[ may have a fractional part. `Gg.Float.max_frac_float` is the greatest positive `float` with a fractional part.

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