Library
Module
Module type
Parameter
Class
Class type
A module for working with floating-point numbers.
Valid syntax for float
s includes:
42.
42.0
(-7.)
3.14
(-0.1234)
123_456.123_456
6.022e23 (* = (6.022 * 10^23) *)
6.022e+23 (* = (6.022 * 10^23) *)
1.602e-19 (* = (1.602 * 10^-19) *)
1e3 (* = (1 * 10 ** 3) = 1000. *)
Without opening this module you can use the .
suffixed operators e.g
1. +. 2. /. 0.25 *. 2. = 17.
But by opening this module locally you can use the un-suffixed operators
Float.((10.0 - 1.5 / 0.5) ** 3.0) = 2401.0
Historical Note: The particular details of floats (e.g. NaN
) are specified by IEEE 754 which is literally hard-coded into almost all CPUs in the world.
Functions for working with floating point numbers.
NaN
as a named value. NaN stands for not a number.
Note comparing values with Float.nan
will always return false
even if the value you are comparing against is also NaN
.
e.g
let isNotANumber x = Float.(x = nan) in
isNotANumber nan = false
For detecting Nan
you should use Float.isNaN
Positive infinity
Float.log ~base:10.0 0.0 = Float.infinity
Negative infinity, see Float.infinity
An approximation of Euler's number.
An approximation of pi.
The smallest representable positive float
. The closest to zero without actually being zero.
For floats greater than maximumSafeInteger
, it no longer holds that Float.(n + 1.) > n
For floats less than minimumSafeInteger
, it no longer holds that Float.(n - 1.) < n
Convert a String
to a float
.
Parses nan
and infinity
case-insensitive.
Examples
Float.ofString "4.667" = Some 4.667
Float.ofString "-4.667" = Some (-4.667)
Float.ofString "Hamster" = None
Float.ofString "NaN" = Some Float.nan
Float.ofString "nan" = Some Float.nan
Float.ofString "Infinity" = Some Float.infinity
Addition for floating point numbers.
Although int
s and float
s support many of the same basic operations such as addition and subtraction you cannot add
an int
and a float
directly which means you need to use functions like Int.toFloat
to convert both values to the same type.
So if you needed to add a List.length
to a float
for some reason, you could:
Float.add 3.14 (Int.toFloat (List.length [1,2,3])) = 6.14
or
Float.roundToInt 3.14 + List.length [1,2,3] = 6
Languages like Java and JavaScript automatically convert int
values to float
values when you mix and match. This can make it difficult to be sure exactly what type of number you are dealing with and cause unexpected behavior.
OCaml has opted for a design that makes all conversions explicit.
Examples
Float.add 3.14 3.14 = 6.28
Float.(3.14 + 3.14 = 6.28)
See Float.add
Subtract numbers
Alternatively the -
operator can be used
Examples
Float.subtract 4.0 3.0 = 1.0
Float.(4.0 - 3.0) = 1.0
See Float.subtract
Multiply numbers
Alternatively the *
operator can be used
Examples
Float.multiply 2.0 7.0 = 14.0
Float.(2.0 * 7.0) = 14.0
See Float.multiply
Floating-point division:
Alternatively the /
operator can be used
Examples
Float.divide 3.14 ~by:2.0 = 1.57
Float.(3.14 / 2.0) = 1.57
See Float.divide
Exponentiation, takes the base first, then the exponent.
Alternatively the **
operator can be used
Examples
Float.power ~base:7.0 ~exponent:3.0 = 343.0
Float.(7.0 ** 3.0) = 343.0
See Float.power
Flips the 'sign' of a float
so that positive floats become negative and negative integers become positive.
Zero stays as it is.
Alternatively an operator is available
Examples
Float.(~- 4.0) = (-4.0)
Float.negate 8 = (-8)
Float.negate (-7) = 7
Float.negate 0 = 0
See Float.negate
Get the absolute value of a number.
Examples
Float.absolute 8. = 8.
Float.absolute (-7) = 7
Float.absolute 0. = 0.
Returns the larger of two float
s, if both arguments are equal, returns the first argument
If either (or both) of the arguments are NaN
, returns NaN
Examples
Float.maximum 7. 9. = 9.
Float.maximum (-4.) (-1.) = (-1.)
Float.(isNaN (maximum 7. nan)) = true
Returns the smaller of two float
s, if both arguments are equal, returns the first argument
If either (or both) of the arguments are NaN
, returns NaN
Examples
Float.minimum 7.0 9.0 = 7.0
Float.minimum (-4.0) (-1.0) = (-4.0)
Float.(isNaN (minimum 7. nan)) = true
Clamps n
within the inclusive lower
and upper
bounds.
Exceptions
Throws an Invalid_argument
exception if lower > upper
Examples
Float.clamp ~lower:0. ~upper:8. 5. = 5.
Float.clamp ~lower:0. ~upper:8. 9. = 8.
Float.clamp ~lower:(-10.) ~upper:(-5.) 5. = -5.
Take the square root of a number.
squareRoot
returns NaN
when its argument is negative. See Float.nan
for more.
Examples
Float.squareRoot 4.0 = 2.0
Float.squareRoot 9.0 = 3.0
Calculate the logarithm of a number with a given base.
Examples
Float.log ~base:10. 100. = 2.
Float.log ~base:2. 256. = 8.
Determine whether a float is an undefined or unrepresentable number.
Note this function is more useful than it might seem since NaN
does not equal Nan
:
Float.(nan = nan) = false
Examples
Float.isNaN (0.0 / 0.0) = true
Float.(isNaN (squareRoot (-1.0))) = true
Float.isNaN (1.0 / 0.0) = false (* Float.infinity {b is} a number *)
Float.isNaN 1. = false
Determine whether a float is finite number. True for any float except Infinity
, -Infinity
or NaN
Notice that NaN
is not finite!
Examples
Float.isFinite (0. / 0.) = false
Float.(isFinite (squareRoot (-1.))) = false
Float.isFinite (1. / 0.) = false
Float.isFinite 1. = true
Float.(isFinite nan) = false
Determine whether a float is positive or negative infinity.
Examples
Float.isInfinite (0. / 0.) = false
Float.(isInfinite (squareRoot (-1.))) = false
Float.isInfinite (1. / 0.) = true
Float.isInfinite 1. = false
Float.(isInfinite nan) = false
Determine whether the passed value is an integer.
Examples
Float.isInteger 4.0 = true
Float.isInteger Float.pi = false
Determine whether the passed value is a safe integer.
Safe integers have the property that x +. 1. > x
.
This is true for numbers between -(2**53 - 1) and 2**53 - 1.
Examples
Float.isSafeInteger 4.0 = true
Float.isSafeInteger Float.pi = false
Float.(isSafeInteger (maximumSafeInteger + 1.)) = false
Checks if a float is between lower
and up to, but not including, upper
.
If lower
is not specified, it's set to to 0.0
.
Exceptions
Throws an Invalid_argument
exception if lower > upper
Examples
Float.inRange ~lower:2. ~upper:4. 3. = true
Float.inRange ~lower:1. ~upper:2. 2. = false
Float.inRange ~lower:5.2 ~upper:7.9 9.6 = false
This type is just an alias for float
.
Its purpose is to make understanding the signatures of the following functions a little easier.
hypotenuse x y
returns the length of the hypotenuse of a right-angled triangle with sides of length x
and y
, or, equivalently, the distance of the point (x, y)
to (0, 0)
.
Examples
Float.hypotenuse 3. 4. = 5.
val degrees : float -> radians
Converts an angle in degrees to Float.radians
.
Examples
Float.degrees 180. = Float.pi
Float.degrees 360. = Float.pi * 2.
Float.degrees 90. = Float.pi /. 2.
val radians : float -> radians
val turns : float -> radians
Convert an angle in turns into Float.radians
.
One turn is equal to 360 degrees.
Examples
Float.(turns (1. / 2.)) = pi
Float.(turns 1. = degrees 360.)
val ofPolar : (float * radians) -> float * float
Convert polar coordinates (radius, radians) to Cartesian coordinates (x,y).
Examples
Float.(ofPolar (squareRoot 2., degrees 45.)) = (1., 1.)
val toPolar : (float * float) -> float * radians
Convert Cartesian coordinates (x, y)
to polar coordinates (radius, radians)
.
Examples
Float.toPolar (-1.0, 0.0) = (1.0, Float.pi)
Float.toPolar (3.0, 4.0) = (5.0, 0.9272952180016122)
Float.toPolar (5.0, 12.0) = (13.0, 1.1760052070951352)
val cos : radians -> float
Figure out the cosine given an angle in radians.
Examples
Float.(cos (degrees 60.)) = 0.5000000000000001
Float.(cos (radians (pi / 3.))) = 0.5000000000000001
val acos : float -> radians
Figure out the arccosine for adjacent / hypotenuse
in radians:
Examples
Float.(acos (radians 1.0 / 2.0)) = Float.radians 1.0471975511965979 (* 60 degrees or pi/3 radians *)
val sin : radians -> float
Figure out the sine given an angle in radians.
Examples
Float.(sin (degrees 30.)) = 0.49999999999999994
Float.(sin (radians (pi / 6.))) = 0.49999999999999994
val asin : float -> radians
Figure out the arcsine for opposite / hypotenuse
in radians:
Examples
Float.(asin (1.0 / 2.0)) = 0.5235987755982989 (* 30 degrees or pi / 6 radians *)
val tan : radians -> float
Figure out the tangent given an angle in radians.
Examples
Float.(tan (degrees 45.)) = 0.9999999999999999
Float.(tan (radians (pi / 4.))) = 0.9999999999999999
Float.(tan (pi / 4.)) = 0.9999999999999999
val atan : float -> radians
This helps you find the angle (in radians) to an (x, y)
coordinate, but in a way that is rarely useful in programming.
You probably want atan2
instead!
This version takes y / x
as its argument, so there is no way to know whether the negative signs comes from the y
or x
value. So as we go counter-clockwise around the origin from point (1, 1)
to (1, -1)
to (-1,-1)
to (-1,1)
we do not get angles that go in the full circle:
Notice that everything is between pi / 2
and -pi/2
. That is pretty useless for figuring out angles in any sort of visualization, so again, check out Float.atan2
instead!
Examples
Float.atan (1. /. 1.) = 0.7853981633974483 (* 45 degrees or pi/4 radians *)
Float.atan (1. /. -1.) = -0.7853981633974483 (* 315 degrees or 7 * pi / 4 radians *)
Float.atan (-1. /. -1.) = 0.7853981633974483 (* 45 degrees or pi/4 radians *)
Float.atan (-1. /. 1.) = -0.7853981633974483 (* 315 degrees or 7 * pi/4 radians *)
This helps you find the angle (in radians) to an (x, y)
coordinate.
So rather than Float.(atan (y / x))
you can Float.atan2 ~y ~x
and you can get a full range of angles:
Examples
Float.atan2 ~y:1. ~x:1. = 0.7853981633974483 (* 45 degrees or pi/4 radians *)
Float.atan2 ~y:1. ~x:(-1.) = 2.3561944901923449 (* 135 degrees or 3 * pi/4 radians *)
Float.atan2 ~y:(-1.) ~x:(-1.) = -(2.3561944901923449) (* 225 degrees or 5 * pi/4 radians *)
Float.atan2 ~y:(-1.) ~x:1. = -(0.7853981633974483) (* 315 degrees or 7 * pi/4 radians *)
The possible direction
s availible when doing Float.round
.
See Float.round
for what each variant represents.
val round : ?direction:direction -> float -> float
Round a number, by default to the to the closest int
with halves rounded `Up
(towards positive infinity)
Other rounding strategies are available by using the optional ~direction
labelelled.
Examples
Float.round 1.2 = 1.0
Float.round 1.5 = 2.0
Float.round 1.8 = 2.0
Float.round -1.2 = -1.0
Float.round -1.5 = -1.0
Float.round -1.8 = -2.0
Towards zero
Float.round ~direction:`Zero 1.2 = 1.0
Float.round ~direction:`Zero 1.5 = 1.0
Float.round ~direction:`Zero 1.8 = 1.0
Float.round ~direction:`Zero (-1.2) = -1.0
Float.round ~direction:`Zero (-1.5) = -1.0
Float.round ~direction:`Zero (-1.8) = -1.0
Away from zero
Float.round ~direction:`AwayFromZero 1.2 = 1.0
Float.round ~direction:`AwayFromZero 1.5 = 1.0
Float.round ~direction:`AwayFromZero 1.8 = 1.0
Float.round ~direction:`AwayFromZero (-1.2) = -1.0
Float.round ~direction:`AwayFromZero (-1.5) = -1.0
Float.round ~direction:`AwayFromZero (-1.8) = -1.0
Towards infinity
This is also known as Float.ceiling
Float.round ~direction:`Up 1.2 = 1.0
Float.round ~direction:`Up 1.5 = 1.0
Float.round ~direction:`Up 1.8 = 1.0
Float.round ~direction:`Up (-1.2) = -1.0
Float.round ~direction:`Up (-1.5) = -1.0
Float.round ~direction:`Up (-1.8) = -1.0
Towards negative infinity
This is also known as Float.floor
List.map ~f:(Float.round ~direction:`Down) [-1.8; -1.5; -1.2; 1.2; 1.5; 1.8] = [-2.0; -2.0; -2.0; 1.0 1.0 1.0]
To the closest integer
Rounding a number x
to the closest integer requires some tie-breaking for when the fraction
part of x
is exactly 0.5
.
Halves rounded towards zero
List.map ~f:(Float.round ~direction:(`Closest `AwayFromZero)) [-1.8; -1.5; -1.2; 1.2; 1.5; 1.8] = [-2.0; -1.0; -1.0; 1.0 1.0 2.0]
Halves rounded away from zero
This method is often known as commercial rounding
List.map ~f:(Float.round ~direction:(`Closest `AwayFromZero)) [-1.8; -1.5; -1.2; 1.2; 1.5; 1.8] = [-2.0; -2.0; -1.0; 1.0 2.0 2.0]
Halves rounded down
List.map ~f:(Float.round ~direction:(`Closest `Down)) [-1.8; -1.5; -1.2; 1.2; 1.5; 1.8] = [-2.0; -2.0; -1.0; 1.0 1.0 2.0]
Halves rounded up
This is the default.
Float.round 1.5
is the same as Float.round ~direction:(`Closest `Up) 1.5
Halves rounded towards the closest even number
Float.round ~direction:(`Closest `ToEven) -1.5 = -2.0
Float.round ~direction:(`Closest `ToEven) -2.5 = -2.0
Floor function, equivalent to Float.round ~direction:`Down
.
Examples
Float.floor 1.2 = 1.0
Float.floor 1.5 = 1.0
Float.floor 1.8 = 1.0
Float.floor -1.2 = -2.0
Float.floor -1.5 = -2.0
Float.floor -1.8 = -2.0
Ceiling function, equivalent to Float.round ~direction:`Up
.
Examples
Float.ceiling 1.2 = 2.0
Float.ceiling 1.5 = 2.0
Float.ceiling 1.8 = 2.0
Float.ceiling -1.2 = (-1.0)
Float.ceiling -1.5 = (-1.0)
Float.ceiling -1.8 = (-1.0)
Ceiling function, equivalent to Float.round ~direction:`Zero
.
Examples
Float.truncate 1.0 = 1.
Float.truncate 1.2 = 1.
Float.truncate 1.5 = 1.
Float.truncate 1.8 = 1.
Float.truncate (-1.2) = -1.
Float.truncate (-1.5) = -1.
Float.truncate (-1.8) = -1.
Converts a float
to an Int
by ignoring the decimal portion. See Float.truncate
for examples.
Returns None
when trying to round a float
which can't be represented as an int
such as Float.nan
or Float.infinity
or numbers which are too large or small.
You probably want to use some form of Float.round
prior to using this function.
Examples
Float.(toInt 1.6) = (Some 1)
Float.(toInt 2.0) = (Some 2)
Float.(toInt 5.683) = (Some 5)
Float.(toInt nan) = None
Float.(toInt infinity) = None
Float.(round 1.6 |> toInt) = Some 2
Convert a float
to a String
The behaviour of this function is platform specific