## 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 `Nat`

, the `1`

ends up changing from
`Num *`

to the more specific `Nat`

, and the expression as a whole
ends up having the type `Nat`

.

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:

`215u8`

is a`215`

value of type`U8`

`76.4f32`

is a`76.4`

value of type`F32`

`123.45dec`

is a`123.45`

value of type`Dec`

`12345nat`

is a`12345`

value of type`Nat`

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:

`U16`

is like`U8`

, except it takes up 16 bits in memory. It can store 65,536 numbers (2^16), ranging from 0 to 65,536.`I16`

is like`U16`

, except it is signed. It can still store the same 65,536 numbers (2^16), ranging from -32,768 to 32,767.

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:

Range | Type | Size |
---|---|---|

` -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` |

Roc also has one variable-size integer type: `Nat`

. The size of `Nat`

is equal
to the size of a memory address, which varies by system. For example, when
compiling for a 64-bit system, `Nat`

is the same as `U64`

. When compiling for a
32-bit system, it's the same as `U32`

.

A common use for `Nat`

is to store the length ("len" for short) of a
collection like a `List`

. 64-bit systems can represent longer
lists in memory than 32-bit systems, which is why the length of a list
is represented as a `Nat`

in Roc.

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.`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.3000000000000000444089209850062616169452667236328125.

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:

- ∞ (infinity)
- -∞ (negative infinity)
*NaN*(not a number)

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

- Dividing a positive
`F64`

by`0.0`

returns ∞. - Dividing a negative
`F64`

by`0.0`

returns -∞. - Dividing a
`F64`

of`0.0`

by`0.0`

returns*NaN*.

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.

**Signed128**

**Signed64**

**Signed32**

**Signed16**

**Signed8**

**Unsigned128**

**Unsigned64**

**Unsigned32**

**Unsigned16**

**Unsigned8**

**Natural**

**Integer** range

**I128**

**I64**

**I32**

**I16**

**I8**

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

**U128**

**U64**

**U32**

**U16**

**U8**

**Nat**

A natural number represented as a 64-bit unsigned integer on 64-bit systems, a 32-bit unsigned integer on 32-bit systems, and so on.

This system-specific size makes it useful for certain data structure
functions like `List.len`

, because the number of elements many data structures
can hold is also system-specific. For example, the maximum number of elements
a `List`

can hold on a 64-bit system fits in a 64-bit unsigned integer, and
on a 32-bit system it fits in 32-bit unsigned integer. This makes `Nat`

a
good fit for `List.len`

regardless of system.

**Decimal**

**Binary64**

**Binary32**

**FloatingPoint** range

**F64**

**F32**

**Dec**

A decimal number.

`Dec`

is the best default choice for representing base-10 decimal numbers
like currency, because it is base-10 under the hood. In contrast,
`F64`

and `F32`

are base-2 under the hood, which can lead to decimal
precision loss even when doing addition and subtraction. For example, when
using `F64`

, running 0.1 + 0.2 returns 0.3000000000000000444089209850062616169452667236328125,
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 precision issues. 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 decimal precision loss isn't as big a concern when
dealing with screen coordinates as it is when dealing with currency.

## Performance Details

`Dec`

typically takes slightly less time than `F64`

to perform addition and
subtraction, but 10-20 times longer to perform multiplication and division.
`sqrt`

and trigonometry are massively slower with `Dec`

than with `F64`

.

**toStr** : Num * -> Str

Convert a number to a `Str`

.

This is the same as calling `Num.format {}`

- so for more details on
exact formatting, see `Num.format`

.

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 `"-∞"`

.

To get strings in hexadecimal, octal, or binary format, use `Num.format`

.

**intCast** : Int a -> Int b

**bytesToU16** : List U8, Nat -> Result U16 [OutOfBounds]

**bytesToU32** : List U8, Nat -> Result U32 [OutOfBounds]

**bytesToU64** : List U8, Nat -> Result U64 [OutOfBounds]

**bytesToU128** : List U8, Nat -> Result U128 [OutOfBounds]

**compare** :
Num a,
Num a
->
[
LT,
EQ,
GT
]

**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.)

**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`

.

**toFrac** : Num * -> Frac *

**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

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 5 7

`Num.add`

can be convenient in pipelines.

Frac.pi |> Num.add 1.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.

**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

`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.

**sin** : Frac a -> Frac a

**cos** : Frac a -> Frac a

**tan** : Frac a -> Frac a

**asin** : Frac a -> Frac a

**acos** : Frac a -> Frac a

**atan** : Frac a -> Frac a

**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

**sqrtChecked** : Frac a -> Result (Frac a) [SqrtOfNegative]

**log** : Frac a -> Frac a

Natural logarithm

**logChecked** : Frac a -> Result (Frac a) [LogNeedsPositive]

**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:

- Dividing a positive
`F64`

or`F32`

by zero returns ∞. - Dividing a negative
`F64`

or`F32`

by zero returns -∞. - Dividing a zero
`F64`

or`F32`

by zero returns*NaN*.

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

**divChecked** : Frac a, Frac a -> Result (Frac a) [DivByZero]

**divCeil** : Int a, Int a -> Int a

**divCeilChecked** : Int a, Int a -> Result (Int a) [DivByZero]

**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

**divTruncChecked** : Int a, Int a -> Result (Int a) [DivByZero]

**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

**remChecked** : Int a, Int a -> Result (Int a) [DivByZero]

**isMultipleOf** : Int a, Int a -> Bool

**bitwiseAnd** : Int a, Int a -> Int a

**bitwiseXor** : Int a, Int a -> Int a

**bitwiseOr** : Int a, Int a -> Int a

**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 == 0b0000_1100

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_0011 2 == 0b0000_1100 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 left is like dividing by factors of two for unsigned integers.

shiftRightBy 0b0010_1000 2 == 0b0000_1010 0b0010_1000 |> shiftRightBy 2 == 0b0000_1010 0b1001_0000 |> shiftRightBy 2 == 0b0010_0100

In some languages `shiftRightBy`

is implemented as a binary operator `>>`

.

**round** : Frac * -> Int *

Round off the given fraction to the nearest integer.

**floor** : Frac * -> Int *

**ceiling** : Frac * -> Int *

**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 -> Nat

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

Num.countLeadingZeroBits 0b0001_1100u8 3 Num.countLeadingZeroBits 0b0000_0000u8 8

**countTrailingZeroBits** : Int a -> Nat

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 -> Nat

Counts the number of set bits in an integer.

Num.countOneBits 0b0001_1100u8 3 Num.countOneBits 0b0000_0000u8 0

**addWrap** : Int range, Int range -> Int range

**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`

.

**subWrap** : Int range, Int range -> Int range

**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`

.

**mulWrap** : Int range, Int range -> Int range

**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.

**minF32** : F32

**maxF32** : F32

**minF64** : F64

**maxF64** : F64

**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.

**toI16** : Int * -> I16

**toI32** : Int * -> I32

**toI64** : Int * -> I64

**toI128** : Int * -> I128

**toU8** : Int * -> U8

**toU16** : Int * -> U16

**toU32** : Int * -> U32

**toU64** : Int * -> U64

**toU128** : Int * -> U128

**toNat** : Int * -> Nat

Converts an `Int`

to a `Nat`

. If the given number doesn't fit in `Nat`

, it will be truncated.
Since `Nat`

has a different maximum number depending on the system you're building
for, this may give a different answer on different systems.

For example, on a 32-bit system, `Num.maxNat`

will return the same answer as
`Num.maxU32`

. This means that calling `Num.toNat 9_000_000_000`

on a 32-bit
system will return `Num.maxU32`

instead of 9 billion, because 9 billion is
higher than `Num.maxU32`

and will not fit in a `Nat`

on a 32-bit system.

However, calling `Num.toNat 9_000_000_000`

on a 64-bit system will return
the `Nat`

value of 9_000_000_000. This is because on a 64-bit system, `Nat`

can
hold up to `Num.maxU64`

, and 9_000_000_000 is lower than `Num.maxU64`

.

To convert a `Frac`

to a `Nat`

, first call either `Num.round`

, `Num.ceil`

, or `Num.floor`

on it, then call this on the resulting `Int`

.

**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`

.