This library comes with some additional numeric functions and constants.

These functions work over many numeric types

```
let qr0 = divRem 7 3 //val qr0 : int * int = (2, 1)
let qr1 = divRem 7I 3I //val qr1 : System.Numerics.BigInteger * System.Numerics.BigInteger = (2, 1)
let qr2 = divRem 7. 3. //val qr2 : float * float = (2.333333333, 0.0) -> using default method.
```

Apart from typical math constants, bounded types comes with `minValue`

and `maxValue`

constants.

Here's an example how can this be used to implement an efficient `findMin`

function

```
let inline findMin (lst: 'a list) =
let rec loop acc = function
| [] -> acc
| x::_ when x = minValue -> x
| x::xs -> loop (if x < acc then x else acc) xs
loop maxValue lst
let minInt = findMin [1;0;12;2]
let minUInt = findMin [1u;0u;12u;2u] // loops only twice
```

Writing code that is generic over different numeric types can be really tedious in F#.

Using this library it becomes an easy task, but it's important to understand the numeric abstractions and its limitations.

In order to have a reasonable type inference over generic types we need strict operations.

For example the F# definition of `(+)`

can take 2 different types, this makes possible to interact with some .NET types that have defined the `(+)`

operator in a very arbitrary way.

For instance you can add a `float`

to a `DateTime`

with the `(+)`

operator, and that `float`

will be interpreted as seconds.

By opening the `FSharpPlus.Math.Generic`

namespace this will no longer be possible, because that's the tradeoff in order to get decent type inference.

Numbers with a G suffix are generics.

```
open FSharpPlus.Math.Generic
let res5Int : int = 5G
let res5UInt : uint32 = 5G
```

Often you need to define generic constants when defining generic functions. Since there is no way to define generic decimal literals in F# at the moment of writing this, we can use divisions:

```
let inline areaOfCircle radio =
let pi =
314159265358979323846264338G
/
100000000000000000000000000G
pi * radio * radio
let area1 = areaOfCircle 5.
let area2 = areaOfCircle 5.0f
let area3 = areaOfCircle 5.0M
```

```
type Vector2d<'T> = Vector2d of 'T * 'T with
static member inline (+) (Vector2d(a:'t, b:'t), Vector2d(c:'t, d:'t)) = Vector2d (((a + c):'t), ((b + d):'t))
static member inline (-) (Vector2d(a:'t, b:'t), Vector2d(c:'t, d:'t)) = Vector2d (((a - c):'t), ((b - d):'t))
static member inline (*) (Vector2d(a:'t, b:'t), Vector2d(c:'t, d:'t)) = Vector2d (((a * c):'t), ((b * d):'t))
static member Return x = Vector2d (x, x)
static member Map(Vector2d(x, y), f) = Vector2d (f x, f y)
static member inline FromBigInt x = let y = fromBigInt x in Vector2d (y, y)
```

Note we don't define overloads for adding a vector to a number

Why? Apart from being tedious they will break math operators strictness

so we will have problems type inferencing generic functions.

OK, but then how to add (subtract, multiply) to a number?

Option 1, explicitely 'lift' the number.

Requires Return and ( + , - , * )

```
let x1 = Vector2d (32,5) + result 7
let x1' = result 7 + Vector2d (32,5)
```

Option 2, use Generic Numbers

Requires `FromBigInt`

and (+,-,*,/)

```
open FSharpPlus.Math.Generic
let x2 = Vector2d (32,5) + 7G
let x2' = 7G + Vector2d (32,5)
```

Option 3, use Applicative Math Operators
Requires only `Map`

```
open FSharpPlus.Math.Applicative
let x3 = Vector2d (32,5) .+ 7
let x3' = 7 +. Vector2d (32,5)
```

We may use types defined in other libraries, let's suppose we have this type Ratio defined somewhere.

```
type Ratio =
struct
val Numerator : bigint
val Denominator : bigint
new (numerator: bigint, denominator: bigint) = {Numerator = numerator; Denominator = denominator}
end
override this.ToString() = this.Numerator.ToString() + " % " + this.Denominator.ToString()
let ratio (a:bigint) (b:bigint) :Ratio =
if b = 0I then failwith "Ratio.%: zero denominator"
let a, b = if b < 0I then (-a, -b) else (a, b)
let gcd = gcd a b
Ratio (a / gcd, b / gcd)
let Ratio (x,y) = x </ratio/> y
type Ratio with
static member inline (/) (a:Ratio, b:Ratio) = (a.Numerator * b.Denominator) </ratio/> (a.Denominator * b.Numerator)
static member inline (+) (a:Ratio, b:Ratio) = (a.Numerator * b.Denominator + b.Numerator * a.Denominator) </ratio/> (a.Denominator * b.Denominator)
static member inline (-) (a:Ratio, b:Ratio) = (a.Numerator * b.Denominator - b.Numerator * a.Denominator) </ratio/> (a.Denominator * b.Denominator)
static member inline (*) (a:Ratio, b:Ratio) = (a.Numerator * b.Numerator) </ratio/> (a.Denominator * b.Denominator)
static member inline Abs (r:Ratio) = (abs r.Numerator) </ratio/> r.Denominator
static member inline Signum (r:Ratio) = (signum r.Numerator) </ratio/> 1I
static member inline FromBigInt (x:bigint) = fromBigInt x </ratio/> 1I
static member inline (~-) (r:Ratio) = -(r.Numerator) </ratio/> r.Denominator
```

Since most Rational implementations have Numerator and Denominator defined we can just use our generic functions on it:

```
let some3_2 = trySqrt (Ratio(9I, 4I))
```

The quadratic function has different results depending on which domain it operates.

For example for real numbers it can have 0 or 2 solutions (arguably also 1 that is a double solution).

But for complex numbers it always has 2 solutions.

```
open FSharpPlus.Math.Generic
let inline quadratic a b c =
let root1 = ( -b + sqrt ( b * b - 4G * a * c) ) / (2G * a)
let root2 = ( -b - sqrt ( b * b - 4G * a * c) ) / (2G * a)
(root1,root2)
let noRes = quadratic 2.0 3G 9G
// val noRes : float * float = (nan, nan)
let res30_15 = quadratic 2.0 -3G -9G
// val res30_15 : float * float = (3.0, -1.5)
let res30_15f = quadratic 2.0f -3G -9G
// val res30_15f : float32 * float32 = (3.0f, -1.5f)
let resCmplx:System.Numerics.Complex * _ = quadratic 2G -3G 9G
// val resCmplx : System.Numerics.Complex * System.Numerics.Complex = ((0.75, -1.98431348329844), (0.75, 1.98431348329844))
let res30_15r:Ratio * _ = quadratic 2G -3G -9G
// val res30_15r : Ratio * Ratio = (3 % 1, -3 % 2)
```

namespace FSharpPlus

val qr0: int * int

val divRem: dividend: 'Num -> divisor: 'Num -> 'Num * 'Num (requires member DivRem)

*<summary>Divides one number by another, returns a tuple with the result and the remainder.</summary>*

<category index="22">Numerics</category>

<category index="22">Numerics</category>

val qr1: System.Numerics.BigInteger * System.Numerics.BigInteger

val qr2: float * float

val findMin: lst: 'a list -> 'a (requires member MinValue and member MaxValue and comparison)

val lst: 'a list (requires member MinValue and member MaxValue and comparison)

'a

type 'T list = List<'T>

val loop: acc: 'a -> ('a list -> 'a) (requires member MinValue and member MaxValue and comparison)

val acc: 'a (requires member MinValue and member MaxValue and comparison)

val x: 'a (requires member MinValue and member MaxValue and comparison)

val minValue<'Num (requires member MinValue)> : 'Num (requires member MinValue)

*<summary>The smallest possible value.</summary>*

<category index="22">Numerics</category>

<category index="22">Numerics</category>

val xs: 'a list (requires member MinValue and member MaxValue and comparison)

val maxValue<'Num (requires member MaxValue)> : 'Num (requires member MaxValue)

*<summary>The largest possible value.</summary>*

<category index="22">Numerics</category>

<category index="22">Numerics</category>

val minInt: int

val minUInt: uint32

namespace FSharpPlus.Math

module Generic
from FSharpPlus.Math

*<summary>
Generic numbers, functions and operators.
By opening this module some common operators become restricted, like (+) to 'T->'T->'T
</summary>*

val res5Int: int

Multiple items

val int: value: 'T -> int (requires member op_Explicit)

--------------------

type int = int32

--------------------

type int<'Measure> = int

val int: value: 'T -> int (requires member op_Explicit)

--------------------

type int = int32

--------------------

type int<'Measure> = int

val res5UInt: uint32

Multiple items

val uint32: value: 'T -> uint32 (requires member op_Explicit)

--------------------

type uint32 = System.UInt32

--------------------

type uint32<'Measure> = uint<'Measure>

val uint32: value: 'T -> uint32 (requires member op_Explicit)

--------------------

type uint32 = System.UInt32

--------------------

type uint32<'Measure> = uint<'Measure>

val areaOfCircle: radio: 'a -> 'a (requires member ( * ) and member (/) and member FromBigInt)

val radio: 'a (requires member ( * ) and member (/) and member FromBigInt)

val pi: 'a (requires member ( * ) and member (/) and member FromBigInt)

val area1: float

val area2: float32

val area3: decimal

'T

Multiple items

union case Vector2d.Vector2d: 'T * 'T -> Vector2d<'T>

--------------------

type Vector2d<'T> = | Vector2d of 'T * 'T static member ( * ) : Vector2d<'t> * Vector2d<'t> -> Vector2d<'t> (requires member ( * )) static member (+) : Vector2d<'t> * Vector2d<'t> -> Vector2d<'t> (requires member ``+``) static member (-) : Vector2d<'t> * Vector2d<'t> -> Vector2d<'t> (requires member (-)) static member FromBigInt: x: bigint -> Vector2d<'a> (requires member FromBigInt) static member Map: Vector2d<'a> * f: ('a -> 'b) -> Vector2d<'b> static member Return: x: 'a -> Vector2d<'a>

union case Vector2d.Vector2d: 'T * 'T -> Vector2d<'T>

--------------------

type Vector2d<'T> = | Vector2d of 'T * 'T static member ( * ) : Vector2d<'t> * Vector2d<'t> -> Vector2d<'t> (requires member ( * )) static member (+) : Vector2d<'t> * Vector2d<'t> -> Vector2d<'t> (requires member ``+``) static member (-) : Vector2d<'t> * Vector2d<'t> -> Vector2d<'t> (requires member (-)) static member FromBigInt: x: bigint -> Vector2d<'a> (requires member FromBigInt) static member Map: Vector2d<'a> * f: ('a -> 'b) -> Vector2d<'b> static member Return: x: 'a -> Vector2d<'a>

val a: 't (requires member ``+``)

't

val b: 't (requires member ``+``)

val c: 't (requires member ``+``)

val d: 't (requires member ``+``)

val a: 't (requires member (-))

val b: 't (requires member (-))

val c: 't (requires member (-))

val d: 't (requires member (-))

val a: 't (requires member ( * ))

val b: 't (requires member ( * ))

val c: 't (requires member ( * ))

val d: 't (requires member ( * ))

val x: 'a

Multiple items

module Map from FSharpPlus

*<summary>
Additional operations on Map<'Key, 'Value>
</summary>*

--------------------

module Map from Microsoft.FSharp.Collections

--------------------

type Map<'Key,'Value (requires comparison)> = interface IReadOnlyDictionary<'Key,'Value> interface IReadOnlyCollection<KeyValuePair<'Key,'Value>> interface IEnumerable interface IComparable interface IEnumerable<KeyValuePair<'Key,'Value>> interface ICollection<KeyValuePair<'Key,'Value>> interface IDictionary<'Key,'Value> new: elements: seq<'Key * 'Value> -> Map<'Key,'Value> member Add: key: 'Key * value: 'Value -> Map<'Key,'Value> member Change: key: 'Key * f: ('Value option -> 'Value option) -> Map<'Key,'Value> ...

--------------------

new: elements: seq<'Key * 'Value> -> Map<'Key,'Value>

module Map from FSharpPlus

--------------------

module Map from Microsoft.FSharp.Collections

--------------------

type Map<'Key,'Value (requires comparison)> = interface IReadOnlyDictionary<'Key,'Value> interface IReadOnlyCollection<KeyValuePair<'Key,'Value>> interface IEnumerable interface IComparable interface IEnumerable<KeyValuePair<'Key,'Value>> interface ICollection<KeyValuePair<'Key,'Value>> interface IDictionary<'Key,'Value> new: elements: seq<'Key * 'Value> -> Map<'Key,'Value> member Add: key: 'Key * value: 'Value -> Map<'Key,'Value> member Change: key: 'Key * f: ('Value option -> 'Value option) -> Map<'Key,'Value> ...

--------------------

new: elements: seq<'Key * 'Value> -> Map<'Key,'Value>

val y: 'a

val f: ('a -> 'b)

val x: bigint

val y: 'a (requires member FromBigInt)

val fromBigInt: x: bigint -> 'Num (requires member FromBigInt)

*<summary>Converts from BigInteger to the inferred destination type.</summary>*

<category index="22">Numerics</category>

<category index="22">Numerics</category>

val x1: Vector2d<int>

val result: x: 'T -> 'Functor<'T> (requires member Return)

*<summary>
Lifts a value into a Functor. Same as return in Computation Expressions.
</summary>*

<category index="2">Applicative</category>

<category index="2">Applicative</category>

val x1': Vector2d<int>

val x2: Vector2d<int>

val x2': Vector2d<int>

module Applicative
from FSharpPlus.Math

*<summary>Math Operators ready to use over Applicative Functors.</summary>*

val x3: Vector2d<int>

val x3': Vector2d<int>

Ratio.Numerator: bigint

type bigint = System.Numerics.BigInteger

Ratio.Denominator: bigint

val numerator: bigint

val denominator: bigint

val this: inref<Ratio>

val ratio: a: bigint -> b: bigint -> Ratio

val a: bigint

val b: bigint

Multiple items

[<Struct>] type Ratio = new: numerator: bigint * denominator: bigint -> Ratio val Numerator: bigint val Denominator: bigint override ToString: unit -> string static member ( * ) : a: Ratio * b: Ratio -> Ratio static member (+) : a: Ratio * b: Ratio -> Ratio static member (-) : a: Ratio * b: Ratio -> Ratio static member (/) : a: Ratio * b: Ratio -> Ratio static member Abs: r: Ratio -> Ratio static member FromBigInt: x: bigint -> Ratio ...

--------------------

Ratio ()

new: numerator: bigint * denominator: bigint -> Ratio

[<Struct>] type Ratio = new: numerator: bigint * denominator: bigint -> Ratio val Numerator: bigint val Denominator: bigint override ToString: unit -> string static member ( * ) : a: Ratio * b: Ratio -> Ratio static member (+) : a: Ratio * b: Ratio -> Ratio static member (-) : a: Ratio * b: Ratio -> Ratio static member (/) : a: Ratio * b: Ratio -> Ratio static member Abs: r: Ratio -> Ratio static member FromBigInt: x: bigint -> Ratio ...

--------------------

Ratio ()

new: numerator: bigint * denominator: bigint -> Ratio

val failwith: message: string -> 'T

val gcd: bigint

Multiple items

val Ratio: x: bigint * y: bigint -> Ratio

--------------------

[<Struct>] type Ratio = new: numerator: bigint * denominator: bigint -> Ratio val Numerator: bigint val Denominator: bigint override ToString: unit -> string static member ( * ) : a: Ratio * b: Ratio -> Ratio static member (+) : a: Ratio * b: Ratio -> Ratio static member (-) : a: Ratio * b: Ratio -> Ratio static member (/) : a: Ratio * b: Ratio -> Ratio static member Abs: r: Ratio -> Ratio static member FromBigInt: x: bigint -> Ratio ...

--------------------

Ratio ()

new: numerator: bigint * denominator: bigint -> Ratio

val Ratio: x: bigint * y: bigint -> Ratio

--------------------

[<Struct>] type Ratio = new: numerator: bigint * denominator: bigint -> Ratio val Numerator: bigint val Denominator: bigint override ToString: unit -> string static member ( * ) : a: Ratio * b: Ratio -> Ratio static member (+) : a: Ratio * b: Ratio -> Ratio static member (-) : a: Ratio * b: Ratio -> Ratio static member (/) : a: Ratio * b: Ratio -> Ratio static member Abs: r: Ratio -> Ratio static member FromBigInt: x: bigint -> Ratio ...

--------------------

Ratio ()

new: numerator: bigint * denominator: bigint -> Ratio

val y: bigint

val a: Ratio

val b: Ratio

val r: Ratio

val abs: value: 'Num -> 'Num (requires member Abs)

*<summary> Gets the absolute value of the given number.
<para /> Rule: signum x * abs x = x </summary>*

<category index="22">Numerics</category>

<param name="value">The input value.</param>

<returns>The absolute value of the input.</returns>

<category index="22">Numerics</category>

<param name="value">The input value.</param>

<returns>The absolute value of the input.</returns>

val signum: value: 'Num -> 'Num (requires member Signum)

*<summary>Sign of the given number
<para /> Rule: signum x * abs x = x </summary>*

<category index="22">Numerics</category>

<param name="value">The input value.</param>

<returns>-1, 0, or 1 depending on the sign of the input.</returns>

<category index="22">Numerics</category>

<param name="value">The input value.</param>

<returns>-1, 0, or 1 depending on the sign of the input.</returns>

val some3_2: Ratio option

val trySqrt: x: 'a -> 'a option (requires member TrySqrt)

*<summary>Square root of a number of any type. Returns None if there is no square root.</summary>*

<category index="22">Numerics</category>

<category index="22">Numerics</category>

val quadratic: a: 'a -> b: 'a -> c: 'a -> 'a * 'a (requires member FromInt32 and member ( * ) and member Sqrt and member (~-) and member (/) and member ``+`` and member (-))

val a: 'a (requires member FromInt32 and member ( * ) and member Sqrt and member (~-) and member (/) and member ``+`` and member (-))

val b: 'a (requires member FromInt32 and member ( * ) and member Sqrt and member (~-) and member (/) and member ``+`` and member (-))

val c: 'a (requires member FromInt32 and member ( * ) and member Sqrt and member (~-) and member (/) and member ``+`` and member (-))

val root1: 'a (requires member FromInt32 and member ( * ) and member Sqrt and member (~-) and member (/) and member ``+`` and member (-))

val sqrt: x: 'b -> 'b (requires member Sqrt)

*<summary>Square root of a number of any type. Throws an exception if there is no square root.</summary>*

<category index="22">Numerics</category>

<category index="22">Numerics</category>

val root2: 'a (requires member FromInt32 and member ( * ) and member Sqrt and member (~-) and member (/) and member ``+`` and member (-))

val noRes: float * float

val res30_15: float * float

val res30_15f: float32 * float32

val resCmplx: System.Numerics.Complex * System.Numerics.Complex

namespace System

namespace System.Numerics

Multiple items

[<Struct>] type Complex = new: real: float * imaginary: float -> unit member Equals: value: Complex -> bool + 1 overload member GetHashCode: unit -> int member ToString: unit -> string + 3 overloads member TryFormat: destination: Span<char> * charsWritten: byref<int> * format: ReadOnlySpan<char> * provider: IFormatProvider -> bool static member ( * ) : left: float * right: Complex -> Complex + 2 overloads static member (+) : left: float * right: Complex -> Complex + 2 overloads static member (-) : left: float * right: Complex -> Complex + 2 overloads static member (/) : left: float * right: Complex -> Complex + 2 overloads static member (<>) : left: Complex * right: Complex -> bool ...

*<summary>Represents a complex number.</summary>*

--------------------

System.Numerics.Complex ()

System.Numerics.Complex(real: float, imaginary: float) : System.Numerics.Complex

[<Struct>] type Complex = new: real: float * imaginary: float -> unit member Equals: value: Complex -> bool + 1 overload member GetHashCode: unit -> int member ToString: unit -> string + 3 overloads member TryFormat: destination: Span<char> * charsWritten: byref<int> * format: ReadOnlySpan<char> * provider: IFormatProvider -> bool static member ( * ) : left: float * right: Complex -> Complex + 2 overloads static member (+) : left: float * right: Complex -> Complex + 2 overloads static member (-) : left: float * right: Complex -> Complex + 2 overloads static member (/) : left: float * right: Complex -> Complex + 2 overloads static member (<>) : left: Complex * right: Complex -> bool ...

--------------------

System.Numerics.Complex ()

System.Numerics.Complex(real: float, imaginary: float) : System.Numerics.Complex

val res30_15r: Ratio * Ratio