# Mathematical Operations and Elementary Functions

Julia provides a complete collection of basic arithmetic and bitwise operators across all of its
numeric primitive types, as well as providing portable, efficient implementations of a comprehensive
collection of standard mathematical functions.

## Arithmetic Operators

The following [arithmetic operators](https://en.wikipedia.org/wiki/Arithmetic#Arithmetic_operations)
are supported on all primitive numeric types:

| Expression | Name           | Description                             |
|:---------- |:-------------- |:----------------------------------------|
| `+x`       | unary plus     | the identity operation                  |
| `-x`       | unary minus    | maps values to their additive inverses  |
| `x + y`    | binary plus    | performs addition                       |
| `x - y`    | binary minus   | performs subtraction                    |
| `x * y`    | times          | performs multiplication                 |
| `x / y`    | divide         | performs division                       |
| `x ÷ y`    | integer divide | x / y, truncated to an integer          |
| `x \ y`    | inverse divide | equivalent to `y / x`                   |
| `x ^ y`    | power          | raises `x` to the `y`th power           |
| `x % y`    | remainder      | equivalent to `rem(x, y)`               |

A numeric literal placed directly before an identifier or parentheses, e.g. `2x` or `2(x + y)`, is treated as a multiplication, except with higher precedence than other binary operations. See [Numeric Literal Coefficients](@ref man-numeric-literal-coefficients) for details.

Julia's promotion system makes arithmetic operations on mixtures of argument types "just work"
naturally and automatically. See [Conversion and Promotion](@ref conversion-and-promotion) for details of the promotion
system.

The ÷ sign can be conveniently typed by writing `\div<tab>` to the REPL or Julia IDE. See the [manual section on Unicode input](@ref Unicode-Input) for more information.

Here are some simple examples using arithmetic operators:

```jldoctest
julia> 1 + 2 + 3
6

julia> 1 - 2
-1

julia> 3*2/12
0.5
```

(By convention, we tend to space operators more tightly if they get applied before other nearby
operators. For instance, we would generally write `-x + 2` to reflect that first `x` gets negated,
and then `2` is added to that result.)

## Boolean Operators

The following [Boolean operators](https://en.wikipedia.org/wiki/Boolean_algebra#Operations) are supported on [`Bool`](@ref) types:

| Expression | Name                                                    |
|:---------- |:--------------------------------------------------------|
| `!x`       | negation                                                |
| `x && y`   | [short-circuiting and](@ref man-conditional-evaluation) |
| `x \|\| y` | [short-circuiting or](@ref man-conditional-evaluation)  |

Negation changes `true` to `false` and vice versa. The short-circuiting operations are explained on the linked page.

## Arithmetic operations with `Bool` values

Note that `Bool` is an integer type, such that `false` is numerically equal to `0` and `true` is numerically equal to `1`. All the usual promotion rules and numeric operators are also defined on it, with a special behavior of arithmetic (non-Boolean) operations when all the arguments are `Bool`: in those cases, the arguments are promoted to `Int` instead of keeping their type. Compare e.g. the following equivalent operations with `Bool` and with a different numeric type (`UInt8`):

```jldoctest
julia> true - true
0

julia> 0x01 - 0x01
0x00
```

Also, when used in multiplication, `false` acts as a *strong zero*:

```jldoctest
julia> NaN * false
0.0

julia> false * Inf
0.0
```

This is useful for preventing the propagation of `NaN` values in quantities that are known to be zero. See [Knuth (1992)](https://arxiv.org/abs/math/9205211) for motivation.

## Bitwise Operators

The following [bitwise operators](https://en.wikipedia.org/wiki/Bitwise_operation#Bitwise_operators)
are supported on all primitive integer types:

| Expression | Name                                                                     |
|:---------- |:------------------------------------------------------------------------ |
| `~x`       | bitwise not                                                              |
| `x & y`    | bitwise and                                                              |
| `x \| y`   | bitwise or                                                               |
| `x ⊻ y`    | bitwise xor (exclusive or)                                               |
| `x ⊼ y`    | bitwise nand (not and)                                                   |
| `x ⊽ y`    | bitwise nor (not or)                                                     |
| `x >>> y`  | [logical shift](https://en.wikipedia.org/wiki/Logical_shift) right       |
| `x >> y`   | [arithmetic shift](https://en.wikipedia.org/wiki/Arithmetic_shift) right |
| `x << y`   | logical/arithmetic shift left                                            |

Here are some examples with bitwise operators:

```jldoctest
julia> ~123
-124

julia> 123 & 234
106

julia> 123 | 234
251

julia> 123 ⊻ 234
145

julia> xor(123, 234)
145

julia> nand(123, 123)
-124

julia> 123 ⊼ 123
-124

julia> nor(123, 124)
-128

julia> 123 ⊽ 124
-128

julia> ~UInt32(123)
0xffffff84

julia> ~UInt8(123)
0x84
```

## Updating operators

Every binary arithmetic and bitwise operator also has an updating version that assigns the result
of the operation back into its left operand. The updating version of the binary operator is formed
by placing a `=` immediately after the operator. For example, writing `x += 3` is equivalent to
writing `x = x + 3`:

```jldoctest
julia> x = 1
1

julia> x += 3
4

julia> x
4
```

The updating versions of all the binary arithmetic and bitwise operators are:

```
+=  -=  *=  /=  \=  ÷=  %=  ^=  &=  |=  ⊻=  >>>=  >>=  <<=
```

!!! note
    An updating operator rebinds the variable on the left-hand side. As a result, the type of the
    variable may change.

    ```jldoctest
    julia> x = 0x01; typeof(x)
    UInt8

    julia> x *= 2 # Same as x = x * 2
    2

    julia> typeof(x)
    Int64
    ```

## [Vectorized "dot" operators](@id man-dot-operators)

For most operators (for example `^`), there is a corresponding
"dot" operator (like `.^`) that is *automatically* defined
to perform `^` element-by-element on arrays.[^1] For example,
`[1, 2, 3] ^ 3` is not defined, since there is no standard
mathematical meaning to "cubing" a (non-square) array, but
`[1, 2, 3] .^ 3` is defined as computing the elementwise
(or "vectorized") result `[1^3, 2^3, 3^3]`. Similarly for unary
operators like `!` or `√`, there is a corresponding `.√` that
applies the operator elementwise.

[^1]:
    Exceptions to this are `:= $= ?: in isa : .. $ :: . ' ... -> ,`

```jldoctest
julia> [1, 2, 3] .^ 3
3-element Vector{Int64}:
  1
  8
 27
```

More specifically, `a .^ b` is parsed as the ["dot" call](@ref man-vectorized)
`(^).(a,b)`, which performs a [broadcast](@ref Broadcasting) operation:
it can combine arrays and scalars, arrays of the same size (performing
the operation elementwise), and even arrays of different shapes (e.g.
combining row and column vectors to produce a matrix). Moreover, like
all vectorized "dot calls," these "dot operators" are
*fusing*. For example, if you compute `2 .* A.^2 .+ sin.(A)` (or
equivalently `@. 2A^2 + sin(A)`, using the [`@.`](@ref @__dot__) macro) for
an array `A`, it performs a *single* loop over `A`, computing `2a^2 + sin(a)`
for each element `a` of `A`. In particular, nested dot calls like `f.(g.(x))`
are fused, and "adjacent" binary operators like `x .+ 3 .* x.^2` are
equivalent to nested dot calls `(+).(x, (*).(3, (^).(x, 2)))`.

Furthermore, "dotted" updating operators like `a .+= b` (or `@. a += b`) are parsed
as `a .= a .+ b`, where `.=` is a fused *in-place* assignment operation
(see the [dot syntax documentation](@ref man-vectorized)).

Note the dot syntax is also applicable to user-defined operators.
For example, if you define `⊗(A, B) = kron(A, B)` to give a convenient
infix syntax `A ⊗ B` for Kronecker products ([`kron`](@ref)), then
`[A, B] .⊗ [C, D]` will compute `[A⊗C, B⊗D]` with no additional coding.

Combining dot operators with numeric literals can be ambiguous.
For example, it is not clear whether `1.+x` means `1. + x` or `1 .+ x`.
Therefore this syntax is disallowed, and spaces must be used around
the operator in such cases.

## Numeric Comparisons

Standard comparison operations are defined for all the primitive numeric types:

| Operator                     | Name                     |
|:---------------------------- |:------------------------ |
| [`==`](@ref)                 | equality                 |
| [`!=`](@ref), [`≠`](@ref !=) | inequality               |
| [`<`](@ref)                  | less than                |
| [`<=`](@ref), [`≤`](@ref <=) | less than or equal to    |
| [`>`](@ref)                  | greater than             |
| [`>=`](@ref), [`≥`](@ref >=) | greater than or equal to |

Here are some simple examples:

```jldoctest
julia> 1 == 1
true

julia> 1 == 2
false

julia> 1 != 2
true

julia> 1 == 1.0
true

julia> 1 < 2
true

julia> 1.0 > 3
false

julia> 1 >= 1.0
true

julia> -1 <= 1
true

julia> -1 <= -1
true

julia> -1 <= -2
false

julia> 3 < -0.5
false
```

Integers are compared in the standard manner -- by comparison of bits. Floating-point numbers
are compared according to the [IEEE 754 standard](https://en.wikipedia.org/wiki/IEEE_754-2008):

  * Finite numbers are ordered in the usual manner.
  * Positive zero is equal but not greater than negative zero.
  * `Inf` is equal to itself and greater than everything else except `NaN`.
  * `-Inf` is equal to itself and less than everything else except `NaN`.
  * `NaN` is not equal to, not less than, and not greater than anything, including itself.

The last point is potentially surprising and thus worth noting:

```jldoctest
julia> NaN == NaN
false

julia> NaN != NaN
true

julia> NaN < NaN
false

julia> NaN > NaN
false
```

and can cause headaches when working with [arrays](@ref man-multi-dim-arrays):

```jldoctest
julia> [1 NaN] == [1 NaN]
false
```

Julia provides additional functions to test numbers for special values, which can be useful in
situations like hash key comparisons:

| Function                | Tests if                  |
|:----------------------- |:------------------------- |
| [`isequal(x, y)`](@ref) | `x` and `y` are identical |
| [`isfinite(x)`](@ref)   | `x` is a finite number    |
| [`isinf(x)`](@ref)      | `x` is infinite           |
| [`isnan(x)`](@ref)      | `x` is not a number       |

[`isequal`](@ref) considers `NaN`s equal to each other:

```jldoctest
julia> isequal(NaN, NaN)
true

julia> isequal([1 NaN], [1 NaN])
true

julia> isequal(NaN, NaN32)
true
```

`isequal` can also be used to distinguish signed zeros:

```jldoctest
julia> -0.0 == 0.0
true

julia> isequal(-0.0, 0.0)
false
```

Mixed-type comparisons between signed integers, unsigned integers, and floats can be tricky. A
great deal of care has been taken to ensure that Julia does them correctly.

For other types, `isequal` defaults to calling [`==`](@ref), so if you want to define
equality for your own types then you only need to add a [`==`](@ref) method. If you define
your own equality function, you should probably define a corresponding [`hash`](@ref) method
to ensure that `isequal(x,y)` implies `hash(x) == hash(y)`.

### Chaining comparisons

Unlike most languages, with the [notable exception of Python](https://en.wikipedia.org/wiki/Python_syntax_and_semantics#Comparison_operators),
comparisons can be arbitrarily chained:

```jldoctest
julia> 1 < 2 <= 2 < 3 == 3 > 2 >= 1 == 1 < 3 != 5
true
```

Chaining comparisons is often quite convenient in numerical code. Chained comparisons use the
`&&` operator for scalar comparisons, and the [`&`](@ref) operator for elementwise comparisons,
which allows them to work on arrays. For example, `0 .< A .< 1` gives a boolean array whose entries
are true where the corresponding elements of `A` are between 0 and 1.

Note the evaluation behavior of chained comparisons:

```jldoctest
julia> v(x) = (println(x); x)
v (generic function with 1 method)

julia> v(1) < v(2) <= v(3)
2
1
3
true

julia> v(1) > v(2) <= v(3)
2
1
false
```

The middle expression is only evaluated once, rather than twice as it would be if the expression
were written as `v(1) < v(2) && v(2) <= v(3)`. However, the order of evaluations in a chained
comparison is undefined. It is strongly recommended not to use expressions with side effects (such
as printing) in chained comparisons. If side effects are required, the short-circuit `&&` operator
should be used explicitly (see [Short-Circuit Evaluation](@ref)).

### Elementary Functions

Julia provides a comprehensive collection of mathematical functions and operators. These mathematical
operations are defined over as broad a class of numerical values as permit sensible definitions,
including integers, floating-point numbers, rationals, and complex numbers,
wherever such definitions make sense.

Moreover, these functions (like any Julia function) can be applied in "vectorized" fashion to
arrays and other collections with the [dot syntax](@ref man-vectorized) `f.(A)`,
e.g. `sin.(A)` will compute the sine of each element of an array `A`.

## Operator Precedence and Associativity

Julia recognizes a large list of characters (or strings of a few characters in some cases) as
operators, each with a defined precedence and associativity.  When an expression contains multiple
operators, the precedence and associativity determine how the expression is parsed into function
calls — though parentheses can always be used to explicitly specify the desired order of
operations.

Most of these [operators are functions](@ref Operators-Are-Functions).[^2]  They can be used with
either functional notation (e.g., `+(a, b)`) or "infix" notation (e.g., `a + b`) — the parser
essentially rewrites infix expressions as function calls.  In functional notation, the grouping of
operations is explicit from the parentheses, so the expression is parsed unambiguously.  When
infix notation is used with more than one operator in an expression and parentheses do not
disambiguate the order, precedence and associativity rules determine how the expression is parsed.

[^2]:
    Some operators are parsed specially: `&& || = += -= *= /= //= \= ^= ÷= %= <<= >>= >>>= |= &=
    ⊻= := $= . ... , -> $ & ::`, as well as the ternary conditional `a ? b : c` and unary quote `:`.

In an expression with different operators, *precedence* determines the order.  For example, `*`
has higher precedence than `+` when used as binary operators, so `1 + 2 * 3` is parsed as
`1 + (2 * 3)`.  In an expression with the same operator used more than once, *associativity*
determines the order.  For example, with a left-associative operator `a ⊗ₗ b ⊗ₗ c` is parsed as
`(a ⊗ₗ b) ⊗ₗ c`; with a right-associative operator `a ⊗ᵣ b ⊗ᵣ c` is parsed as `a ⊗ᵣ (b ⊗ᵣ c)`.

Some operators are neither left- nor right-associative.  As discussed [above](@ref
Chaining-comparisons), comparison operators such as `<` and `==` are *chaining* operators, with no
fixed order of evaluation.  Another such group is the [*varargs*](@ref Varargs-Functions)
operators `+`, `++`, and `*` (but not other addition or multiplication operators).  These are
parsed as varargs calls when chained, rather than nested binary calls: `a + b + c` is parsed as
`+(a, b, c)` and `a*b*c` is parsed as `*(a, b, c)`.  The `++` operator is also parsed in this
way, but note that it has no methods defined in `Base`.  Also note that juxtaposition of
[numeric literal coefficients](@ref man-numeric-literal-coefficients) to denote multiplication
(for example `2x` to mean `2*x`) is more of a syntactic form than an operator.  Describing its
associativity doesn't make sense, except to state the obvious point that `24x` means `24*x`
rather than `2*(4*x)` or `(2*4)*x`. They are treated as multiplications with higher precedence
than any other binary operation, with the exception of `^` where they have higher precedence
only as the exponent.

```jldoctest
julia> x = 3; 2x^2
18

julia> x = 3; 2^2x
64
```

It is also possible to define additional operators by appending suffixes to most operators.[^3]
The valid suffixes include the Unicode combining characters, along with the subscripts, superscripts, and various
primes (such as `′ ″ ‴ ⁗ ‵ ‶ ‷`) listed in
[`src/flisp/julia_opsuffs.h`](https://github.com/JuliaLang/julia/blob/master/src/flisp/julia_opsuffs.h).  The
resulting operators can be used with either functional or infix notation, and have the same precedence and
associativity as the base operator.  For example, `⋆̂ᵝ₁′` could be defined as a function, and used as an infix operator
with the same precedence and associativity as `⋆` and `*`.  However, operators ending with a subscript or superscript
letter must be followed by a space when used in infix notation to distinguish them from variable names that begin
with a subscript or superscript letter.  For example, if `+ᵃ` is an operator, then `+ᵃx` must be written as `+ᵃ x`
to distinguish it from `+ ᵃx`.

[^3]:
    Exceptions to this are tuple, assignment, ternary if, control flow, dots, unary, declaration, field access, and unary quote operators,
    as well as `<: >: in isa $`

The following table lists Julia's operators, from highest precedence to lowest.  Those listed
outside of parentheses are already defined in the `Base` module; those listed inside parentheses
are not currently defined in `Base`, but are available to be defined by standard libraries,
packages, or user code.  For example, `⋅` and `×` are defined in the standard library's
`LinearAlgebra` package.  Some of the latter lists are incomplete; for a complete listing of
*every* Julia operator and its precedence, see the top of this file:
[`src/julia-parser.scm`](https://github.com/JuliaLang/julia/blob/master/src/julia-parser.scm).

| Category       | Operators                                                                                  | Associativity      |
|:-------------- |:------------------------------------------------------------------------------------------ |:--------------     |
| Unary quote    | `:`                                                                                        | Not composable[^4] |
| Field access   | `.`                                                                                        | Left[^4]           |
| Postfix unary  | `'`                                                                                        | Left               |
| Declaration    | `::`                                                                                       | Left               |
| Exponentiation | `^` (`↑ ↓ ⇵ ⟰ ⟱ ⤈ ⤉ ⤊ ⤋ ⤒ ⤓`, etc.)                                                        | Right[^5]          |
| Unary          | `+ - ! ~ √ ∛ ∜ <: >:` (`¬ ⋆ ± ∓`)                                                          | Right[^6]          |
| Juxtaposition  | Implicit multiplication by numeric literal coefficients                                    | Not composable     |
| Bitshift       | `<< >> >>>`                                                                                | Left               |
| Fraction       | `//`                                                                                       | Left               |
| Multiplication | `* / ÷ % & ∘ \ ∩ ⊼` (`⋅ × ⋆ ⊗ ⊘ ⊠ ⊡ ⊓ ∧`, etc.)                                            | Left[^7]           |
| Addition       | `+ - \| ∪ ⊻ ⊽` (`++ ± ∓ ⊕ ⊖ ⊞ ⊟ ⊔ ∨ $`, etc.)                                              | Left[^7]           |
| Dots           | `: ...` (`.. … ⁝ ⋮ ⋱ ⋰ ⋯`)                                                                 | Left[^8]           |
| Pipe           | `\|>`                                                                                      | Left               |
| Pipe           | (`<\|`)                                                                                    | Right              |
| Comparison     | `in isa > < >= ≥ <= ≤ == === ≡ != ≠ !== ≢ ∈ ∉ ∋ ∌ ⊆ ⊈ ⊊ ≈ ≉ ⊇ ⊉ ⊋ <: >:` (`⊂ ⊄ ∝ ∥`, etc.) | Chaining[^9]       |
| Control flow   | `&&` followed by `\|\|`                                                                    | Right              |
| Arrow          | (`← → ↔ ↚ ↛ ↢ ↣ ↦ ↤ ↮ ⇎ ⇍ ⇏ ⇐ ⇒ ⇔`, etc.)                                                  | Right              |
| Ternary if     | `?:`                                                                                       | Right[^10]         |
| Pair           | `=>`                                                                                       | Right              |
| Assignment     | `= += -= *= /= //= \= ^= ÷= %= <<= >>= >>>= \|= &= ⊻= ->` (`~ ≔ ⩴ ≕ :=`)                   | Right[^11]         |
| Tuple          | `,`                                                                                        | Vararg             |

[^4]:
    Spaces are not allowed around the `.` getproperty or the `:` expr operators
[^5]:
    Unary operators and juxtaposition of numeric literals are lower precedence than `^` only as the *first argument*.  For example, `2^-3`, `x^√2`, and `2^3x` are parsed as `2^(-3)`, `x^(√2)`, and `2^(3*x)`; whereas `-2^3`, `√x^2`, `2^3*x`, and `2x^3` are parsed as `-(2^3)`, `√(x^2)`, `(2^3)*x`, and `2*(x^3)`
[^6]:
    Most unary operators can be composed, except `++` which is a distinct *binary* operator, and `--` which produces a `ParseError`.  Other compositions of unary operators are parsed with right-associativity — e.g., `√√-a` as `√(√(-a))`
[^7]:
    The operators `+`, `++` and `*` are vararg calls rather than left-associative.  For example, `a + b + c` is parsed as `+(a, b, c)` not `+(+(a, b),c)`.  However, the fallback methods for `+(a, b, c, d...)` and `*(a, b, c, d...)` both default to left-associative evaluation.  Note that `++` is not defined in `Base`, but is parsed in the same way
[^8]:
    The operator `:` is parsed into groups of three. For example `a : b : c : d : e` is parsed as `(:)((:)(a, b, c), d, e)`\
    The postfix unary operator `...` may only be followed by an operator of lower precedence\
    Due to a parser bug ([#58763](https://github.com/JuliaLang/julia/issues/58763)), dots operators other than `:` cannot currently be composed. This may be fixed to 3-arg grouping like `:` or normal left associativity in a future version
[^9]:
    Comparisons can be [chained](@ref "Chaining comparisons").  For example, `a < b < c` is essentially the same as `a < b && b < c`.  However, the order of evaluation is undefined
[^10]:
    Pair and assignment operators are lower precedence than `?:` only as the *first argument*. For example, `a => b ? c => d : e => f` parses as `a => (b ? (c => d) : (e => f))`
[^11]:
    Except for the `->` function operator, assignment operators become lower precedence than commas if they are a top-level expression. For example, `a, b = c` parses as `(a, b) = c`; but `(a, b = c)` parses as `(a, (b = c))`

You can also find the numerical precedence for any binary or ternary operator via the
built-in function `Base.operator_precedence`, where higher numbers take precedence:

```jldoctest
julia> Base.operator_precedence(:+), Base.operator_precedence(:*), Base.operator_precedence(:.)
(11, 12, 17)

julia> Base.operator_precedence(:sin), Base.operator_precedence(:+=), Base.operator_precedence(:(=))  # (Note the necessary parens on `:(=)`)
(0, 1, 1)
```

A symbol representing the operator associativity can also be found by calling the built-in function `Base.operator_associativity`:

```jldoctest
julia> Base.operator_associativity(:-), Base.operator_associativity(:+), Base.operator_associativity(:^)
(:left, :none, :right)

julia> Base.operator_associativity(:⊗), Base.operator_associativity(:sin), Base.operator_associativity(:→)
(:left, :none, :right)
```

Note that symbols such as `:sin` return precedence `0`. This value represents invalid operators and not
operators of lowest precedence. Similarly, such operators are assigned associativity `:none`.
Some valid operators, such as `+`, `++`, `*`, and the comparison operators, also report associativity
`:none` because they are neither left- nor right-associative.

## Numerical Conversions

Julia supports three forms of numerical conversion, which differ in their handling of inexact
conversions.

  * The notation `T(x)` or `convert(T, x)` converts `x` to a value of type `T`.

      * If `T` is a floating-point type, the result is the nearest representable value, which could be
        positive or negative infinity.
      * If `T` is an integer type, an `InexactError` is raised if `x` is not representable by `T`.
  * `x % T` converts an integer `x` to a value of integer type `T` congruent to `x` modulo `2^n`,
    where `n` is the number of bits in `T`. In other words, the binary representation is truncated
    to fit.
  * The [Rounding functions](@ref) take a type `T` as an optional argument. For example, `round(Int,x)`
    is a shorthand for `Int(round(x))`.

The following examples show the different forms.

```jldoctest
julia> Int8(127)
127

julia> Int8(128)
ERROR: InexactError: trunc(Int8, 128)
Stacktrace:
[...]

julia> Int8(127.0)
127

julia> Int8(3.14)
ERROR: InexactError: Int8(3.14)
Stacktrace:
[...]

julia> Int8(128.0)
ERROR: InexactError: Int8(128.0)
Stacktrace:
[...]

julia> 127 % Int8
127

julia> 128 % Int8
-128

julia> round(Int8,127.4)
127

julia> round(Int8,127.6)
ERROR: InexactError: Int8(128.0)
Stacktrace:
[...]
```

See [Conversion and Promotion](@ref conversion-and-promotion) for how to define your own conversions and promotions.

### Rounding functions

| Function              | Description                      | Return type |
|:--------------------- |:-------------------------------- |:----------- |
| [`round(x)`](@ref)    | round `x` to the nearest integer | `typeof(x)` |
| [`round(T, x)`](@ref) | round `x` to the nearest integer | `T`         |
| [`floor(x)`](@ref)    | round `x` towards `-Inf`         | `typeof(x)` |
| [`floor(T, x)`](@ref) | round `x` towards `-Inf`         | `T`         |
| [`ceil(x)`](@ref)     | round `x` towards `+Inf`         | `typeof(x)` |
| [`ceil(T, x)`](@ref)  | round `x` towards `+Inf`         | `T`         |
| [`trunc(x)`](@ref)    | round `x` towards zero           | `typeof(x)` |
| [`trunc(T, x)`](@ref) | round `x` towards zero           | `T`         |

### Division functions

| Function                   | Description                                                                                               |
|:-------------------------- |:--------------------------------------------------------------------------------------------------------- |
| [`div(x, y)`](@ref), `x÷y` | truncated division; quotient rounded towards zero                                                         |
| [`fld(x, y)`](@ref)        | floored division; quotient rounded towards `-Inf`                                                         |
| [`cld(x, y)`](@ref)        | ceiling division; quotient rounded towards `+Inf`                                                         |
| [`rem(x, y)`](@ref), `x%y` | remainder; satisfies `x == div(x, y)*y + rem(x, y)`; sign matches `x`                                     |
| [`mod(x, y)`](@ref)        | modulus; satisfies `x == fld(x, y)*y + mod(x, y)`; sign matches `y`                                       |
| [`mod1(x, y)`](@ref)       | `mod` with offset 1; returns `r∈(0, y]` for `y>0` or `r∈[y, 0)` for `y<0`, where `mod(r, y) == mod(x, y)` |
| [`mod2pi(x)`](@ref)        | modulus with respect to 2pi;  `0 <= mod2pi(x) < 2pi`                                                      |
| [`divrem(x, y)`](@ref)     | returns `(div(x, y),rem(x, y))`                                                                           |
| [`fldmod(x, y)`](@ref)     | returns `(fld(x, y), mod(x, y))`                                                                          |
| [`gcd(x, y...)`](@ref)     | greatest positive common divisor of `x`, `y`,...                                                          |
| [`lcm(x, y...)`](@ref)     | least positive common multiple of `x`, `y`,...                                                            |

### Sign and absolute value functions

| Function                 | Description                                                |
|:------------------------ |:---------------------------------------------------------- |
| [`abs(x)`](@ref)         | a positive value with the magnitude of `x`                 |
| [`abs2(x)`](@ref)        | the squared magnitude of `x`                               |
| [`sign(x)`](@ref)        | indicates the sign of `x`, returning -1, 0, or +1          |
| [`signbit(x)`](@ref)     | indicates whether the sign bit is on (true) or off (false) |
| [`copysign(x, y)`](@ref) | a value with the magnitude of `x` and the sign of `y`      |
| [`flipsign(x, y)`](@ref) | a value with the magnitude of `x` and the sign of `x*y`    |

### Powers, logs and roots

| Function                      | Description                                                                |
|:----------------------------- |:-------------------------------------------------------------------------- |
| [`sqrt(x)`](@ref), `√x`       | square root of `x`                                                         |
| [`cbrt(x)`](@ref), `∛x`       | cube root of `x`                                                           |
| [`fourthroot(x)`](@ref), `∜x` | fourth root of `x`                                                         |
| [`hypot(x, y)`](@ref)         | hypotenuse of right-angled triangle with other sides of length `x` and `y` |
| [`exp(x)`](@ref)              | natural exponential function at `x`                                        |
| [`expm1(x)`](@ref)            | accurate `exp(x) - 1` for `x` near zero                                    |
| [`ldexp(x, n)`](@ref)         | `x * 2^n` computed efficiently for integer values of `n`                   |
| [`log(x)`](@ref)              | natural logarithm of `x`                                                   |
| [`log(b, x)`](@ref)           | base `b` logarithm of `x`                                                  |
| [`log2(x)`](@ref)             | base 2 logarithm of `x`                                                    |
| [`log10(x)`](@ref)            | base 10 logarithm of `x`                                                   |
| [`log1p(x)`](@ref)            | accurate `log(1 + x)` for `x` near zero                                    |
| [`exponent(x)`](@ref)         | binary exponent of `x`                                                     |
| [`significand(x)`](@ref)      | binary significand (a.k.a. mantissa) of a floating-point number `x`        |

For an overview of why functions like [`hypot`](@ref), [`expm1`](@ref), and [`log1p`](@ref)
are necessary and useful, see John D. Cook's excellent pair of blog posts on the subject: [expm1, log1p, erfc](https://www.johndcook.com/blog/2010/06/07/math-library-functions-that-seem-unnecessary/),
and [hypot](https://www.johndcook.com/blog/2010/06/02/whats-so-hard-about-finding-a-hypotenuse/).

### Trigonometric and hyperbolic functions

All the standard trigonometric and hyperbolic functions are also defined:

```
sin    cos    tan    cot    sec    csc
sinh   cosh   tanh   coth   sech   csch
asin   acos   atan   acot   asec   acsc
asinh  acosh  atanh  acoth  asech  acsch
sinc   cosc
```

These are all single-argument functions, with [`atan`](@ref) also accepting two arguments
corresponding to a traditional [`atan2`](https://en.wikipedia.org/wiki/Atan2) function.

Additionally, [`sinpi(x)`](@ref) and [`cospi(x)`](@ref) are provided for more accurate computations
of [`sin(pi * x)`](@ref) and [`cos(pi * x)`](@ref) respectively.

In order to compute trigonometric functions with degrees instead of radians, suffix the function
with `d`. For example, [`sind(x)`](@ref) computes the sine of `x` where `x` is specified in degrees.
The complete list of trigonometric functions with degree variants is:

```
sind   cosd   tand   cotd   secd   cscd
asind  acosd  atand  acotd  asecd  acscd
```

### Special functions

Many other special mathematical functions are provided by the package
[SpecialFunctions.jl](https://github.com/JuliaMath/SpecialFunctions.jl).
