## Num

### Num range

Represents a number that could be either an `Int` or a `Frac`.

This is useful for functions that can work on either, for example `Num.add`, whose type is:

`add : Num a, Num a -> Num a`

The number 1.5 technically has the type `Num (Fraction *)`, so when you pass two of them to `Num.add`, the answer you get is `3.0 : Num (Fraction *)`.

Similarly, the number 0x1 (that is, the integer 1 in hexadecimal notation) technically has the type `Num (Integer *)`, so when you pass two of them to `Num.add`, the answer you get is `2 : Num (Integer *)`.

The type `Frac a` is defined to be an alias for `Num (Fraction a)`, so `3.0 : Num (Fraction *)` is the same value as `3.0 : Frac *`. Similarly, the type `Int a` is defined to be an alias for `Num (Integer a)`, so `2 : Num (Integer *)` is the same value as `2 : Int *`.

In this way, the `Num` type makes it possible to have `1 + 0x1` return `2 : Int *` and `1.5 + 1.5` return `3.0 : Frac`.

## Number Literals

Number literals without decimal points (like `0`, `4` or `360`) have the type `Num *` at first, but usually end up taking on a more specific type based on how they're used.

For example, in `(1 + List.len myList)`, the `1` has the type `Num *` at first, but because `List.len` returns a `U64`, the `1` ends up changing from `Num *` to the more specific `U64`, and the expression as a whole ends up having the type `U64`.

Sometimes number literals don't become more specific. For example, the `Num.toStr` function has the type `Num * -> Str`. This means that when calling `Num.toStr (5 + 6)`, the expression `(5 + 6)` still has the type `Num *`. When this happens, `Num *` defaults to being an `I64` - so this addition expression would overflow if either 5 or 6 were replaced with a number big enough to cause addition overflow on an `I64` value.

If this default of `I64` is not big enough for your purposes, you can add an `i128` to the end of the number literal, like so:

`Num.toStr 5_000_000_000i128`

This `i128` suffix specifies that you want this number literal to be an `I128` instead of a `Num *`. All the other numeric types have suffixes just like `i128`; here are some other examples:

In practice, these are rarely needed. It's most common to write number literals without any suffix.

### Int range

A fixed-size integer - that is, a number with no fractional component.

Integers come in two flavors: signed and unsigned. Signed integers can be negative ("signed" refers to how they can incorporate a minus sign), whereas unsigned integers cannot be negative.

Since integers have a fixed size, the size you choose determines both the range of numbers it can represent, and also how much memory it takes up.

`U8` is an an example of an integer. It is an unsigned `Int` that takes up 8 bits (aka 1 byte) in memory. The `U` is for Unsigned and the 8 is for 8 bits. Because it has 8 bits to work with, it can store 256 numbers (2^8), and because it is unsigned, its min value is 0. This means the 256 numbers it can store range from 0 to 255.

`I8` is a signed integer that takes up 8 bits. The `I` is for Integer, since integers in mathematics are signed by default. Because it has 8 bits just like `U8`, it can store 256 numbers (still 2^8), but because it is signed, the range is different. Its 256 numbers range from -128 to 127.

Here are some other examples:

This pattern continues up to `U128` and `I128`.

## Performance Details

In general, using smaller numeric sizes means your program will use less memory. However, if a mathematical operation results in an answer that is too big or too small to fit in the size available for that answer (which is typically the same size as the inputs), then you'll get an overflow error.

As such, minimizing memory usage without causing overflows involves choosing number sizes based on your knowledge of what numbers you expect your program to encounter at runtime.

Minimizing memory usage does not imply maximum runtime speed! CPUs are typically fastest at performing integer operations on integers that are the same size as that CPU's native machine word size. That means a 64-bit CPU is typically fastest at executing instructions on `U64` and `I64` values, whereas a 32-bit CPU is typically fastest on `U32` and `I32` values.

Putting these factors together, here are some reasonable guidelines for optimizing performance through integer size choice:

• Start by deciding if this integer should allow negative numbers, and choose signed or unsigned accordingly.
• Next, think about the range of numbers you expect this number to hold. Choose the smallest size you will never expect to overflow, no matter the inputs your program receives. (Validating inputs for size, and presenting the user with an error if they are too big, can help guard against overflow.)
• Finally, if a particular numeric calculation is running too slowly, you can try experimenting with other number sizes. This rarely makes a meaningful difference, but some processors can operate on different number sizes at different speeds.

All number literals without decimal points are compatible with `Int` values.

You can optionally put underscores in your `Int` literals. They have no effect on the number's value, but can make large numbers easier to read.

`1_000_000`

Integers come in two flavors: signed and unsigned.

• Unsigned integers can never be negative. The lowest value they can hold is zero.
• Signed integers can be negative.

Integers also come in different sizes. Choosing a size depends on your performance needs and the range of numbers you need to represent. At a high level, the general trade-offs are:

• Larger integer sizes can represent a wider range of numbers. If you absolutely need to represent numbers in a certain range, make sure to pick an integer size that can hold them!
• Smaller integer sizes take up less memory. These savings rarely matter in variables and function arguments, but the sizes of integers that you use in data structures can add up. This can also affect whether those data structures fit in cache lines, which can be a performance bottleneck.
• Certain CPUs work faster on some numeric sizes than others. If the CPU is taking too long to run numeric calculations, you may find a performance improvement by experimenting with numeric sizes that are larger than otherwise necessary. However, in practice, doing this typically degrades overall performance, so be careful to measure properly!

Here are the different fixed size integer types:

RangeTypeSize
` -128``I8`1 Byte
` 127`
-------------------------------------------------------------------------
` 0``U8`1 Byte
` 255`
-------------------------------------------------------------------------
` -32_768``I16`2 Bytes
` 32_767`
-------------------------------------------------------------------------
` 0``U16`2 Bytes
` 65_535`
-------------------------------------------------------------------------
` -2_147_483_648``I32`4 Bytes
` 2_147_483_647`
-------------------------------------------------------------------------
` 0``U32`4 Bytes
` (over 4 billion) 4_294_967_295`
-------------------------------------------------------------------------
` -9_223_372_036_854_775_808``I64`8 Bytes
` 9_223_372_036_854_775_807`
-------------------------------------------------------------------------
` 0``U64`8 Bytes
` (over 18 quintillion) 18_446_744_073_709_551_615`
-------------------------------------------------------------------------
`-170_141_183_460_469_231_731_687_303_715_884_105_728``I128`16 Bytes
` 170_141_183_460_469_231_731_687_303_715_884_105_727`
-------------------------------------------------------------------------
` (over 340 undecillion) 0``U128`16 Bytes
` 340_282_366_920_938_463_463_374_607_431_768_211_455`

If any operation would result in an `Int` that is either too big or too small to fit in that range (e.g. calling `Num.maxI32 + 1`), then the operation will overflow. When an overflow occurs, the program will crash.

As such, it's very important to design your code not to exceed these bounds! If you need to do math outside these bounds, consider using a larger numeric size.

### Frac range

A fixed-size number with a fractional component.

Roc fractions come in two flavors: fixed-point base-10 and floating-point base-2.

• `Dec` is a 128-bit fixed-point base-10 number. It's a great default choice, especially when precision is important - for example when representing currency. With `Dec`, `0.1 + 0.2` returns `0.3`. `Dec` has 18 decimal places of precision and a range from `-170_141_183_460_469_231_731.687303715884105728` to `170_141_183_460_469_231_731.687303715884105727`.
• `F64` and `F32` are floating-point base-2 numbers. They sacrifice precision for lower memory usage and improved performance on some operations. This makes them a good fit for representing graphical coordinates. With `F64`, `0.1 + 0.2` returns `0.30000000000000004`.

If you don't specify a type, Roc will default to using `Dec` because it's the least error-prone overall. For example, suppose you write this:

`wasItPrecise = 0.1 + 0.2 == 0.3`

The value of `wasItPrecise` here will be `Bool.true`, because Roc uses `Dec` by default when there are no types specified.

In contrast, suppose we use `f32` or `f64` for one of these numbers:

`wasItPrecise = 0.1f64 + 0.2 == 0.3`

Here, `wasItPrecise` will be `Bool.false` because the entire calculation will have been done in a base-2 floating point calculation, which causes noticeable precision loss in this case.

The floating-point numbers (`F32` and `F64`) also have three values which are not ordinary finite numbers. They are:

These values are different from ordinary numbers in that they only occur when a floating-point calculation encounters an error. For example:

These rules come from the IEEE-754 floating point standard. Because almost all modern processors are built to this standard, deviating from these rules has a significant performance cost! Since the most common reason to choose `F64` or `F32` over `Dec` is access to hardware-accelerated performance, Roc follows these rules exactly.

There's no literal syntax for these error values, but you can check to see if you ended up with one of them by using #isNaN, #isFinite, and #isInfinite. Whenever a function in this module could return one of these values, that possibility is noted in the function's documentation.

## Performance Details

On typical modern CPUs, performance is similar between `Dec`, `F64`, and `F32` for addition and subtraction. For example, `F32` and `F64` do addition using a single CPU floating-point addition instruction, which typically takes a few clock cycles to complete. In contrast, `Dec` does addition using a few CPU integer arithmetic instructions, each of which typically takes only one clock cycle to complete. Exact numbers will vary by CPU, but they should be similar overall.

`Dec` is significantly slower for multiplication and division. It not only needs to do more arithmetic instructions than `F32` and `F64` do, but also those instructions typically take more clock cycles to complete.

With `Num.sqrt` and trigonometry functions like `Num.cos`, there is an even bigger performance difference. `F32` and `F64` can do these in a single instruction, whereas `Dec` needs entire custom procedures - which use loops and conditionals. If you need to do performance-critical trigonometry or square roots, either `F64` or `F32` is probably a better choice than the usual default choice of `Dec`, despite the precision problems they bring.

### I8

A signed 8-bit integer, ranging from -128 to 127

### F64

`F64` represents decimal numbers less precisely than `Dec` does, but operations on it can be faster because CPUs have hardware-level support for `F64` but not `Dec`. There are other tradeoffs between the two, such as:

• `Dec` has a fixed number of digits it can represent before the decimal point, and a fixed number it can represent after the decimal point. In contrast, `F64`'s decimal point can "float"—which conceptually means if you don't need many digits before the decimal point, you can get more digits of precision afterwards (and vice versa).
• `Dec` represents its number internally in base-10, whereas `F64` uses base-2. This can lead to imprecise answers like `0.1 + 0.2` returning `0.3` for `Dec` and `0.30000000000000004` for `F64`. This is not a bug; rather, it's a consequence of `F64`'s base-2 representation.
• `Dec` always gives a precise answer (or an error), whereas `F64` can lose precision. For example, increasing a very large `F64` number (using addition, perhaps) can result in the whole number portion being incorrect. `1234567890123456789 + 100` correctly results in a number ending in `889` for `Dec`, but results in a number ending `800` in `F64` due to precision loss.

### F32

This works just like `F64` (see its docs for a comparison with `Dec`) except it's smaller. That in turn means it takes up less memory, but can store smaller numbers (and becomes imprecise more easily than `F64` does).

### Dec

A decimal number.

`Dec` is a more precise way to represent decimal numbers (like currency) than `F32` and `F64` are, because `Dec` is represented in memory as base-10. In contrast, `F64` and `F32` are base-2 in memory, which can lead to decimal precision loss even when doing addition and subtraction. For example, when using `F64`, `0.1 + 0.2` returns 0.30000000000000004, whereas when using `Dec`, `0.1 + 0.2` returns 0.3.

Under the hood, a `Dec` is an `I128`, and operations on it perform base-10 fixed-point arithmetic with 18 decimal places of precision.

This means a `Dec` can represent whole numbers up to slightly over 170 quintillion, along with 18 decimal places. (To be precise, it can store numbers between `-170_141_183_460_469_231_731.687303715884105728` and `170_141_183_460_469_231_731.687303715884105727`.) Why 18 decimal places? It's the highest number of decimal places where you can still convert any `U64` to a `Dec` without losing information.

There are some use cases where `F64` and `F32` can be better choices than `Dec` despite their issues with base-10 numbers. For example, in graphical applications they can be a better choice for representing coordinates because they take up less memory, certain relevant calculations run faster (see performance details, below), and base-10 generally isn't as big a concern when dealing with screen coordinates as it is when dealing with currency.

Another scenario where `F64` can be a better choice than `Dec` is when representing extremely small numbers. The smallest positive `F64` that can be represented without precision loss is 2^(−1074), which is about 5 * 10^(-324). Here is that number next to the smallest `Dec` that can be represented:

• Smallest `F64`: 0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005
• Smallest `Dec`: 0.000000000000000001

This is because floating-point numbers like `F64` can gain more digits of precision after the `.` when they aren't using as many digits before the `.` - and this applies the most if the digit before `.` is `0`. So whereas `Dec` always has 18 digits after the `.`, the number of digits after the `.` that `F32` can `F64` can represent without precision loss depends on what comes before it.

## Performance Details

CPUs have dedicated instructions for many `F32` and `F64` operations, but none for `Dec`. Internally, `Dec` is represented as a 128-bit integer and uses multiple instructions to perform fractional operations. This gives `F32` and `F64` performance advantages for many operations.

Here's a comparison of about how long `Dec` takes to perform a given operation compared to `F64`, based on benchmarks on an M1 CPU:

Keep in mind that arithmetic instructions are basically the fastest thing a CPU does, so (for example) a network request that takes 10 milliseconds to complete would go on this list as about 10000000x. So these performance differences might be more or less noticeable than the base-10 representation differences depending on the use case.

### e : Frac *

Euler's number (e)

### pi : Frac *

Archimedes' constant (π)

### tau : Frac *

Circle constant (τ)

### toStr : Num * -> Str

Convert a number to a `Str`.

`Num.toStr 42`

Only `Frac` values will include a decimal point, and they will always include one.

```Num.toStr 4.2
Num.toStr 4.0```

When this function is given a non-finite `F64` or `F32` value, the returned string will be `"NaN"`, `"∞"`, or `"-∞"`.

### isLt : Num a, Num a -> Bool

Returns `Bool.true` if the first number is less than the second.

`a < b` is shorthand for `Num.isLt a b`.

If either argument is NaN, returns `Bool.false` no matter what. (NaN is defined to be unordered.)

```5
|> Num.isLt 6```

### isGt : Num a, Num a -> Bool

Returns `Bool.true` if the first number is greater than the second.

`a > b` is shorthand for `Num.isGt a b`.

If either argument is NaN, returns `Bool.false` no matter what. (NaN is defined to be unordered.)

```6
|> Num.isGt 5```

### isLte : Num a, Num a -> Bool

Returns `Bool.true` if the first number is less than or equal to the second.

`a <= b` is shorthand for `Num.isLte a b`.

If either argument is NaN, returns `Bool.false` no matter what. (NaN is defined to be unordered.)

### isGte : Num a, Num a -> Bool

Returns `Bool.true` if the first number is greater than or equal to the second.

`a >= b` is shorthand for `Num.isGte a b`.

If either argument is NaN, returns `Bool.false` no matter what. (NaN is defined to be unordered.)

### isApproxEq : Frac a, Frac a, { rtol ? Frac a, atol ? Frac a } -> Bool

Returns `Bool.true` if the first number and second number are within a specific threshold

A specific relative and absolute tolerance can be provided to change the threshold

This function is symmetric: `Num.isApproxEq a b == Num.isApproxEq b a`

If either argument is NaN, returns `Bool.false` no matter what. (NaN is defined to be unordered.)

### isZero : Num a -> Bool

Returns `Bool.true` if the number is `0`, and `Bool.false` otherwise.

### isEven : Int a -> Bool

A number is even if dividing it by 2 gives a remainder of 0.

Examples of even numbers: 0, 2, 4, 6, 8, -2, -4, -6, -8

### isOdd : Int a -> Bool

A number is odd if dividing it by 2 gives a remainder of 1.

Examples of odd numbers: 1, 3, 5, 7, -1, -3, -5, -7

### isPositive : Num a -> Bool

Positive numbers are greater than `0`.

### isNegative : Num a -> Bool

Negative numbers are less than `0`.

### isNaN : Frac * -> Bool

Returns `Bool.true` if the `Frac` is not a number as defined by IEEE-754

`Num.isNaN (0 / 0)`

### isInfinite : Frac * -> Bool

Returns `Bool.true` if the `Frac` is positive or negative infinity as defined by IEEE-754

```Num.isInfinite (1 / 0)

Num.isInfinite (-1 / 0)```

### isFinite : Frac * -> Bool

Returns `Bool.true` if the `Frac` is not an infinity as defined by IEEE-754

`Num.isFinite 42`

### abs : Num a -> Num a

Returns the absolute value of the number.

• For a positive number, returns the same number.
• For a negative number, returns the same number except positive.
• For zero, returns zero.
```Num.abs 4

Num.abs -2.5

Num.abs 0

Num.abs 0.0```

This is safe to use with any `Frac`, but it can cause overflow when used with certain `Int` values.

For example, calling #Num.abs on the lowest value of a signed integer (such as `Num.minI64` or `Num.minI32`) will cause overflow. This is because, for any given size of signed integer (32-bit, 64-bit, etc.) its negated lowest value turns out to be 1 higher than the highest value it can represent. (For this reason, calling `Num.neg` on the lowest signed value will also cause overflow.)

Calling this on an unsigned integer (like `U32` or `U64`) never does anything.

### absDiff : Num a, Num a -> Num a

Returns the absolute difference between two numbers.

```Num.absDiff 5 3

Num.absDiff -3 5

Num.absDiff 3.0 5.0```

If the answer to this operation can't fit in the return value (e.g. an `I8` answer that's higher than 127 or lower than -128), the result is an overflow. For `F64` and `F32`, overflow results in an answer of either ∞ or -∞. For all other number types, overflow results in a panic.

### neg : Num a -> Num a

Returns a negative number when given a positive one, and vice versa.

```Num.neg 5

Num.neg -2.5

Num.neg 0

Num.neg 0.0```

!! Num.neg is not completely implemented for all types in all contexts, see github.com/roc-lang/roc/issues/6959 You can use `\someNum -> 0 - someNum` as a workaround.

This is safe to use with any `Frac`, but it can cause overflow when used with certain `Int` values.

For example, calling #Num.neg on the lowest value of a signed integer (such as `Num.minI64` or `Num.minI32`) will cause overflow. This is because, for any given size of signed integer (32-bit, 64-bit, etc.) its negated lowest value turns out to be 1 higher than the highest value it can represent. (For this reason, calling #Num.abs on the lowest signed value will also cause overflow.)

Additionally, calling #Num.neg on any unsigned integer (such as any `U64` or `U32` value) other than zero will cause overflow.

(It will never crash when given a `Frac`, however, because of how floating point numbers represent positive and negative numbers.)

### add : Num a, Num a -> Num a

Adds two numbers of the same type.

(To add an `Int` and a `Frac`, first convert one so that they both have the same type. There are functions in this module that can convert both `Int` to `Frac` and the other way around.)

`a + b` is shorthand for `Num.add a b`.

```5 + 7

`Num.add` can be convenient in pipelines.

```Frac.pi

If the answer to this operation can't fit in the return value (e.g. an `I8` answer that's higher than 127 or lower than -128), the result is an overflow. For `F64` and `F32`, overflow results in an answer of either ∞ or -∞. For all other number types, overflow results in a panic.

### sub : Num a, Num a -> Num a

Subtracts two numbers of the same type.

(To subtract an `Int` and a `Frac`, first convert one so that they both have the same type. There are functions in this module that can convert both `Int` to `Frac` and the other way around.)

`a - b` is shorthand for `Num.sub a b`.

```7 - 5

Num.sub 7 5```

`Num.sub` can be convenient in pipelines.

```Frac.pi
|> Num.sub 2.0```

If the answer to this operation can't fit in the return value (e.g. an `I8` answer that's higher than 127 or lower than -128), the result is an overflow. For `F64` and `F32`, overflow results in an answer of either ∞ or -∞. For all other number types, overflow results in a panic.

### mul : Num a, Num a -> Num a

Multiplies two numbers of the same type.

(To multiply an `Int` and a `Frac`, first convert one so that they both have the same type. There are functions in this module that can convert both `Int` to `Frac` and the other way around.)

`a * b` is shorthand for `Num.mul a b`.

```5 * 7

Num.mul 5 7```

`Num.mul` can be convenient in pipelines.

```Frac.pi
|> Num.mul 2.0```

If the answer to this operation can't fit in the return value (e.g. an `I8` answer that's higher than 127 or lower than -128), the result is an overflow. For `F64` and `F32`, overflow results in an answer of either ∞ or -∞. For all other number types, overflow results in a panic.

### min : Num a, Num a -> Num a

Obtains the smaller between two numbers of the same type.

```Num.min 100 0

Num.min 3.0 -3.0```

### max : Num a, Num a -> Num a

Obtains the greater between two numbers of the same type.

```Num.max 100 0

Num.max 3.0 -3.0```

### sqrt : Frac a -> Frac a

Returns an approximation of the absolute value of a `Frac`'s square root.

The square root of a negative number is an irrational number, and `Frac` only supports rational numbers. As such, you should make sure never to pass this function a negative number! Calling `sqrt` on a negative `Dec` will cause a panic.

Calling `sqrt` on `F32` and `F64` values follows these rules:

These rules come from the IEEE-754 floating point standard. Because almost all modern processors are built to this standard, deviating from these rules has a significant performance cost! Since the most common reason to choose `F64` or `F32` over `Dec` is access to hardware-accelerated performance, Roc follows these rules exactly.

```Num.sqrt 4.0

Num.sqrt 1.5

Num.sqrt 0.0

Num.sqrt -4.0f64```

### log : Frac a -> Frac a

Natural logarithm

### div : Frac a, Frac a -> Frac a

Divides one `Frac` by another.

`a / b` is shorthand for `Num.div a b`.

Division by zero is undefined in mathematics. As such, you should make sure never to pass zero as the denominator to this function! Calling `div` on a `Dec` denominator of zero will cause a panic.

Calling `div` on `F32` and `F64` values follows these rules:

These rules come from the IEEE-754 floating point standard. Because almost all modern processors are built to this standard, deviating from these rules has a significant performance cost! Since the most common reason to choose `F64` or `F32` over `Dec` is access to hardware-accelerated performance, Roc follows these rules exactly.

To divide an `Int` and a `Frac`, first convert the `Int` to a `Frac` using one of the functions in this module like #toDec.

```5.0 / 7.0

Num.div 5 7```

`Num.div` can be convenient in pipelines.

```Num.pi
|> Num.div 2.0```

### divTrunc : Int a, Int a -> Int a

Divides two integers, truncating the result towards zero.

`a // b` is shorthand for `Num.divTrunc a b`.

Division by zero is undefined in mathematics. As such, you should make sure never to pass zero as the denominator to this function! If you do, it will crash.

```5 // 7

Num.divTrunc 5 7

8 // -3

Num.divTrunc 8 -3```

### rem : Int a, Int a -> Int a

Obtains the remainder (truncating modulo) from the division of two integers.

`a % b` is shorthand for `Num.rem a b`.

```5 % 7

Num.rem 5 7

-8 % -3

Num.rem -8 -3```

### bitwiseAnd : Int a, Int a -> Int a

Does a "bitwise and". Each bit of the output is 1 if the corresponding bit of x AND of y is 1, otherwise it's 0.

### bitwiseXor : Int a, Int a -> Int a

Does a "bitwise exclusive or". Each bit of the output is the same as the corresponding bit in x if that bit in y is 0, and it's the complement of the bit in x if that bit in y is 1.

### bitwiseOr : Int a, Int a -> Int a

Does a "bitwise or". Each bit of the output is 0 if the corresponding bit of x OR of y is 0, otherwise it's 1.

### bitwiseNot : Int a -> Int a

Returns the complement of x - the number you get by switching each 1 for a 0 and each 0 for a 1. This is the same as -x - 1.

### shiftLeftBy : Int a, U8 -> Int a

Bitwise left shift of a number by another

The least significant bits always become 0. This means that shifting left is like multiplying by factors of two for unsigned integers.

```shiftLeftBy 0b0000_0011 2 == 0b0000_1100

0b0000_0101 |> shiftLeftBy 2 == 0b0001_0100```

In some languages `shiftLeftBy` is implemented as a binary operator `<<`.

### shiftRightBy : Int a, U8 -> Int a

Bitwise arithmetic shift of a number by another

The most significant bits are copied from the current.

```shiftRightBy 0b0000_1100 2 == 0b0000_0011

0b0001_0100 |> shiftRightBy 2 == 0b0000_0101

0b1001_0000 |> shiftRightBy 2 == 0b1110_0100```

In some languages `shiftRightBy` is implemented as a binary operator `>>>`.

### shiftRightZfBy : Int a, U8 -> Int a

Bitwise logical right shift of a number by another

The most significant bits always become 0. This means that shifting right is like dividing by factors of two for unsigned integers.

```shiftRightZfBy 0b0010_1000 2 == 0b0000_1010

0b0010_1000 |> shiftRightZfBy 2 == 0b0000_1010

0b1001_0000 |> shiftRightZfBy 2 == 0b0010_0100```

In some languages `shiftRightZfBy` is implemented as a binary operator `>>`.

### round : Frac * -> Int *

Round off the given fraction to the nearest integer.

### pow : Frac a, Frac a -> Frac a

Raises a `Frac` to the power of another `Frac`.

For an `Int` alternative to this function, see `Num.powInt`

### powInt : Int a, Int a -> Int a

Raises an integer to the power of another, by multiplying the integer by itself the given number of times.

This process is known as exponentiation by squaring.

For a `Frac` alternative to this function, which supports negative exponents, see #Num.pow.

## Warning

It is very easy for this function to produce an answer so large it causes an overflow.

### countLeadingZeroBits : Int a -> U8

Counts the number of most-significant (leading in a big-Endian sense) zeroes in an integer.

```Num.countLeadingZeroBits 0b0001_1100u8

3

8```

### countTrailingZeroBits : Int a -> U8

Counts the number of least-significant (trailing in a big-Endian sense) zeroes in an integer.

```Num.countTrailingZeroBits 0b0001_1100u8

2

Num.countTrailingZeroBits 0b0000_0000u8

8```

### countOneBits : Int a -> U8

Counts the number of set bits in an integer.

```Num.countOneBits 0b0001_1100u8

3

Num.countOneBits 0b0000_0000u8

0```

### addSaturated : Num a, Num a -> Num a

Adds two numbers, clamping on the maximum representable number rather than overflowing.

This is the same as `Num.add` except for the saturating behavior if the addition is to overflow. For example, if `x : U8` is 200 and `y : U8` is 100, `addSaturated x y` will yield 255, the maximum value of a `U8`.

### addChecked : Num a, Num a -> Result (Num a) [Overflow]

Adds two numbers and checks for overflow.

This is the same as `Num.add` except if the operation overflows, instead of panicking or returning ∞ or -∞, it will return `Err Overflow`.

### subSaturated : Num a, Num a -> Num a

Subtracts two numbers, clamping on the minimum representable number rather than overflowing.

This is the same as `Num.sub` except for the saturating behavior if the subtraction is to overflow. For example, if `x : U8` is 10 and `y : U8` is 20, `subSaturated x y` will yield 0, the minimum value of a `U8`.

### subChecked : Num a, Num a -> Result (Num a) [Overflow]

Subtracts two numbers and checks for overflow.

This is the same as `Num.sub` except if the operation overflows, instead of panicking or returning ∞ or -∞, it will return `Err Overflow`.

### mulSaturated : Num a, Num a -> Num a

Multiplies two numbers, clamping on the maximum representable number rather than overflowing.

This is the same as `Num.mul` except for the saturating behavior if the addition is to overflow.

### mulChecked : Num a, Num a -> Result (Num a) [Overflow]

Multiplies two numbers and checks for overflow.

This is the same as `Num.mul` except if the operation overflows, instead of panicking or returning ∞ or -∞, it will return `Err Overflow`.

### minI8 : I8

Returns the lowest number that can be stored in an `I8` without underflowing its available memory and crashing.

For reference, this number is `-128`.

Note that the positive version of this number is larger than `Num.maxI8`, which means if you call `Num.abs` on `Num.minI8`, it will overflow and crash!

### maxI8 : I8

Returns the highest number that can be stored in an `I8` without overflowing its available memory and crashing.

For reference, this number is `127`.

Note that this is smaller than the positive version of `Num.minI8`, which means if you call `Num.abs` on `Num.minI8`, it will overflow and crash!

### minU8 : U8

Returns the lowest number that can be stored in a `U8` without underflowing its available memory and crashing.

For reference, this number is zero, because `U8` is unsigned, and zero is the lowest unsigned number. Unsigned numbers cannot be negative.

### maxU8 : U8

Returns the highest number that can be stored in a `U8` without overflowing its available memory and crashing.

For reference, this number is `255`.

### minI16 : I16

Returns the lowest number that can be stored in an `I16` without underflowing its available memory and crashing.

For reference, this number is `-32_768`.

Note that the positive version of this number is larger than `Num.maxI16`, which means if you call `Num.abs` on `Num.minI16`, it will overflow and crash!

### maxI16 : I16

Returns the highest number that can be stored in an `I16` without overflowing its available memory and crashing.

For reference, this number is `32_767`.

Note that this is smaller than the positive version of `Num.minI16`, which means if you call `Num.abs` on `Num.minI16`, it will overflow and crash!

### minU16 : U16

Returns the lowest number that can be stored in a `U16` without underflowing its available memory and crashing.

For reference, this number is zero, because `U16` is unsigned, and zero is the lowest unsigned number. Unsigned numbers cannot be negative.

### maxU16 : U16

Returns the highest number that can be stored in a `U16` without overflowing its available memory and crashing.

For reference, this number is `65_535`.

### minI32 : I32

Returns the lowest number that can be stored in an `I32` without underflowing its available memory and crashing.

For reference, this number is `-2_147_483_648`.

Note that the positive version of this number is larger than `Num.maxI32`, which means if you call `Num.abs` on `Num.minI32`, it will overflow and crash!

### maxI32 : I32

Returns the highest number that can be stored in an `I32` without overflowing its available memory and crashing.

For reference, this number is `2_147_483_647`, which is over 2 million.

Note that this is smaller than the positive version of `Num.minI32`, which means if you call `Num.abs` on `Num.minI32`, it will overflow and crash!

### minU32 : U32

Returns the lowest number that can be stored in a `U32` without underflowing its available memory and crashing.

For reference, this number is zero, because `U32` is unsigned, and zero is the lowest unsigned number. Unsigned numbers cannot be negative.

### maxU32 : U32

Returns the highest number that can be stored in a `U32` without overflowing its available memory and crashing.

For reference, this number is `4_294_967_295`.

### minI64 : I64

Returns the lowest number that can be stored in an `I64` without underflowing its available memory and crashing.

For reference, this number is `-9_223_372_036_854_775_808`, which is under 9 quintillion.

Note that the positive version of this number is larger than `Num.maxI64`, which means if you call `Num.abs` on `Num.minI64`, it will overflow and crash!

### maxI64 : I64

Returns the highest number that can be stored in an `I64` without overflowing its available memory and crashing.

For reference, this number is `9_223_372_036_854_775_807`, which is over 9 quintillion.

Note that this is smaller than the positive version of `Num.minI64`, which means if you call `Num.abs` on `Num.minI64`, it will overflow and crash!

### minU64 : U64

Returns the lowest number that can be stored in a `U64` without underflowing its available memory and crashing.

For reference, this number is zero, because `U64` is unsigned, and zero is the lowest unsigned number. Unsigned numbers cannot be negative.

### maxU64 : U64

Returns the highest number that can be stored in a `U64` without overflowing its available memory and crashing.

For reference, this number is `18_446_744_073_709_551_615`, which is over 18 quintillion.

### minI128 : I128

Returns the lowest number that can be stored in an `I128` without underflowing its available memory and crashing.

For reference, this number is `-170_141_183_460_469_231_731_687_303_715_884_105_728`. which is under 170 undecillion.

Note that the positive version of this number is larger than `Num.maxI128`, which means if you call `Num.abs` on `Num.minI128`, it will overflow and crash!

### maxI128 : I128

Returns the highest number that can be stored in an `I128` without overflowing its available memory and crashing.

For reference, this number is `170_141_183_460_469_231_731_687_303_715_884_105_727`, which is over 170 undecillion.

Note that this is smaller than the positive version of `Num.minI128`, which means if you call `Num.abs` on `Num.minI128`, it will overflow and crash!

### minU128 : U128

Returns the lowest number that can be stored in a `U128` without underflowing its available memory and crashing.

For reference, this number is zero, because `U128` is unsigned, and zero is the lowest unsigned number. Unsigned numbers cannot be negative.

### maxU128 : U128

Returns the highest number that can be stored in a `U128` without overflowing its available memory and crashing.

For reference, this number is `340_282_366_920_938_463_463_374_607_431_768_211_455`, which is over 340 undecillion.

### toI8 : Int * -> I8

Converts an `Int` to an `I8`. If the given number can't be precisely represented in an `I8`, the returned number may be different from the given number.

### toF32 : Num * -> F32

Converts a `Num` to an `F32`. If the given number can't be precisely represented in an `F32`, the returned number may be different from the given number.

### toF64 : Num * -> F64

Converts a `Num` to an `F64`. If the given number can't be precisely represented in an `F64`, the returned number may be different from the given number.

### toI8Checked : Int * -> Result I8 [OutOfBounds]

Converts a `Int` to an `I8`. If the given integer can't be precisely represented in an `I8`, returns `Err OutOfBounds`.

### withoutDecimalPoint : Dec -> I128

Turns a `Dec` into its `I128` representation by removing the decimal point. This is equivalent to multiplying the `Dec` by 10^18.

### withDecimalPoint : I128 -> Dec

Turns a `I128` into the coresponding `Dec` by adding the decimal point. This is equivalent to dividing the `I128` by 10^18.

### f32ToParts : F32 -> { sign : Bool, exponent : U8, fraction : U32 }

Splits a `F32` into its components according to IEEE 754 standard.

### f64ToParts : F64 -> { sign : Bool, exponent : U16, fraction : U64 }

Splits a `F64` into its components according to IEEE 754 standard.

### f32FromParts : { sign : Bool, exponent : U8, fraction : U32 } -> F32

Combine parts of a `F32` according to IEEE 754 standard. The fraction should not be bigger than 0x007F_FFFF, any bigger value will be truncated.

### f64FromParts : { sign : Bool, exponent : U16, fraction : U64 } -> F64

Combine parts of a `F64` according to IEEE 754 standard. The fraction should not be bigger than 0x000F_FFFF_FFFF_FFFF, any bigger value will be truncated. The exponent should not be bigger than 0x07FF, any bigger value will be truncated.

### nanF32 : F32

The value for not-a-number for a `F32` according to the IEEE 754 standard.

### nanF64 : F64

The value for not-a-number for a `F64` according to the IEEE 754 standard.

### infinityF32 : F32

The value for infinity for a `F32` according to the IEEE 754 standard.

### infinityF64 : F64

The value for infinity for a `F64` according to the IEEE 754 standard.