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 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 | inverse divide | equivalent to y/x |
x^y | power | raises x to the y th power |
x%y | remainder | equivalent to rem(x,y) |
as well as the negation on Bool
types:
Expression | Name | Description |
---|---|---|
!x | negation | changes true to false and vice versa |
Julia’s promotion system makes arithmetic operations on mixtures of argument types “just work” naturally and automatically. See Conversion and Promotion for details of the promotion system.
Here are some simple examples using arithmetic operators:
julia>1+2+36julia>1-2-1julia>3*2/120.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.)
Bitwise Operators¶
The following 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 | logical shift right |
x>>y | arithmetic shift right |
x<<y | logical/arithmetic shift left |
Here are some examples with bitwise operators:
julia>~123-124julia>123&234106julia>123|234251julia>123$234145julia>~UInt32(123)0xffffff84julia>~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
:
julia>x=11julia>x+=34julia>x4
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.
julia>x=0x01;typeof(x)UInt8julia>x*=2#Same as x = x * 22julia>isa(x,Int)true
Numeric Comparisons¶
Standard comparison operations are defined for all the primitive numeric types:
Operator | Name |
---|---|
== | equality |
!= ≠ | inequality |
< | less than |
<= ≤ | less than or equal to |
> | greater than |
>= ≥ | greater than or equal to |
Here are some simple examples:
julia>1==1truejulia>1==2falsejulia>1!=2truejulia>1==1.0truejulia>1<2truejulia>1.0>3falsejulia>1>=1.0truejulia>-1<=1truejulia>-1<=-1truejulia>-1<=-2falsejulia>3<-0.5false
Integers are compared in the standard manner — by comparison of bits. Floating-point numbers are compared according to the IEEE 754 standard:
- 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 exceptNaN
.-Inf
is equal to itself and less then everything else exceptNaN
.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:
julia>NaN==NaNfalsejulia>NaN!=NaNtruejulia>NaN<NaNfalsejulia>NaN>NaNfalse
and can cause especial headaches with Arrays:
julia>[1NaN]==[1NaN]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) | x and y are identical |
isfinite(x) | x is a finite number |
isinf(x) | x is infinite |
isnan(x) | x is not a number |
isequal()
considers NaN
s equal to each other:
julia>isequal(NaN,NaN)truejulia>isequal([1NaN],[1NaN])truejulia>isequal(NaN,NaN32)true
isequal()
can also be used to distinguish signed zeros:
julia>-0.0==0.0truejulia>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 ==()
, so if you want to
define equality for your own types then you only need to add a ==()
method. If you define your own equality function, you should probably
define a corresponding hash()
method to ensure that isequal(x,y)
implies hash(x)==hash(y)
.
Chaining comparisons¶
Unlike most languages, with the notable exception of Python, comparisons can be arbitrarily chained:
julia>1<2<=2<3==3>2>=1==1<3!=5true
Chaining comparisons is often quite convenient in numerical code.
Chained comparisons use the &&
operator for scalar comparisons,
and the &
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.
The operator .<
is intended for array objects; the operation
A.<B
is valid only if A
and B
have the same dimensions. The
operator returns an array with boolean entries and with the same dimensions
as A
and B
. Such operators are called elementwise; Julia offers a
suite of elementwise operators: .*
, .+
, etc. Some of the elementwise
operators can take a scalar operand such as the example 0.<A.<1
in
the preceding paragraph.
This notation means that the scalar operand should be replicated for each entry of
the array.
Note the evaluation behavior of chained comparisons:
julia>v(x)=(println(x);x)v(genericfunction with1method)julia>v(1)<v(2)<=v(3)213truejulia>v(1)>v(2)<=v(3)21false
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).
Operator Precedence¶
Julia applies the following order of operations, from highest precedence to lowest:
Category | Operators |
---|---|
Syntax | . followed by :: |
Exponentiation | ^ and its elementwise equivalent .^ |
Fractions | // and .// |
Multiplication | */%&\ and .*./.%.\ |
Bitshifts | <<>>>>> and .<<.>>.>>> |
Addition | +-|$ and .+.- |
Syntax | :.. followed by |> |
Comparisons | ><>=<======!=!==<: and .>.<.>=.<=.==.!= |
Control flow | && followed by || followed by ? |
Assignments | =+=-=*=/=//=\=^=÷=%=|=&=$=<<=>>=>>>= and .+=.-=.*=./=.//=.\=.^=.÷=.%= |
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 complexes, 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
syntax f.(A)
, e.g. sin.(A)
will compute the elementwise
sine of each element of an array A
. See Dot Syntax for Vectorizing Functions:.
Numerical Conversions¶
Julia supports three forms of numerical conversion, which differ in their handling of inexact conversions.
- The notation
T(x)
orconvert(T,x)
convertsx
to a value of typeT
.- 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, anInexactError
is raised ifx
is not representable byT
.
- If
x%T
converts an integerx
to a value of integer typeT
congruent tox
modulo2^n
, wheren
is the number of bits inT
. In other words, the binary representation is truncated to fit.- The Rounding functions take a type
T
as an optional argument. For example,round(Int,x)
is a shorthand forInt(round(x))
.
The following examples show the different forms.
julia>Int8(127)127julia>Int8(128)ERROR:InexactError()inInt8(::Int64)at./sysimg.jl:53...julia>Int8(127.0)127julia>Int8(3.14)ERROR:InexactError()inInt8(::Float64)at./sysimg.jl:53...julia>Int8(128.0)ERROR:InexactError()inInt8(::Float64)at./sysimg.jl:53...julia>127%Int8127julia>128%Int8-128julia>round(Int8,127.4)127julia>round(Int8,127.6)ERROR:InexactError()intrunc(::Type{Int8},::Float64)at./float.jl:458inround(::Type{Int8},::Float64)at./float.jl:211...
See Conversion and Promotion for how to define your own conversions and promotions.
Rounding functions¶
Function | Description | Return type |
---|---|---|
round(x) | round x to the nearest integer | typeof(x) |
round(T,x) | round x to the nearest integer | T |
floor(x) | round x towards -Inf | typeof(x) |
floor(T,x) | round x towards -Inf | T |
ceil(x) | round x towards +Inf | typeof(x) |
ceil(T,x) | round x towards +Inf | T |
trunc(x) | round x towards zero | typeof(x) |
trunc(T,x) | round x towards zero | T |
Division functions¶
Function | Description |
---|---|
div(x,y) | truncated division; quotient rounded towards zero |
fld(x,y) | floored division; quotient rounded towards -Inf |
cld(x,y) | ceiling division; quotient rounded towards +Inf |
rem(x,y) | remainder; satisfies x==div(x,y)*y+rem(x,y) ; sign matches x |
mod(x,y) | modulus; satisfies x==fld(x,y)*y+mod(x,y) ; sign matches y |
mod1(x,y) | 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) | modulus with respect to 2pi; 0<=mod2pi(x) <2pi |
divrem(x,y) | returns (div(x,y),rem(x,y)) |
fldmod(x,y) | returns (fld(x,y),mod(x,y)) |
gcd(x,y...) | greatest positive common divisor of x , y ,... |
lcm(x,y...) | least positive common multiple of x , y ,... |
Sign and absolute value functions¶
Function | Description |
---|---|
abs(x) | a positive value with the magnitude of x |
abs2(x) | the squared magnitude of x |
sign(x) | indicates the sign of x , returning -1, 0, or +1 |
signbit(x) | indicates whether the sign bit is on (true) or off (false) |
copysign(x,y) | a value with the magnitude of x and the sign of y |
flipsign(x,y) | a value with the magnitude of x and the sign of x*y |
Powers, logs and roots¶
Function | Description |
---|---|
sqrt(x) √x | square root of x |
cbrt(x) ∛x | cube root of x |
hypot(x,y) | hypotenuse of right-angled triangle with other sides of length x and y |
exp(x) | natural exponential function at x |
expm1(x) | accurate exp(x)-1 for x near zero |
ldexp(x,n) | x*2^n computed efficiently for integer values of n |
log(x) | natural logarithm of x |
log(b,x) | base b logarithm of x |
log2(x) | base 2 logarithm of x |
log10(x) | base 10 logarithm of x |
log1p(x) | accurate log(1+x) for x near zero |
exponent(x) | binary exponent of x |
significand(x) | binary significand (a.k.a. mantissa) of a floating-point number x |
For an overview of why functions like hypot()
, expm1()
, and log1p()
are necessary and useful, see John D. Cook’s excellent pair
of blog posts on the subject: expm1, log1p,
erfc,
and
hypot.
Trigonometric and hyperbolic functions¶
All the standard trigonometric and hyperbolic functions are also defined:
sincostancotseccscsinhcoshtanhcothsechcschasinacosatanacotasecacscasinhacoshatanhacothasechacschsinccoscatan2
These are all single-argument functions, with the exception of atan2, which gives the angle in radians between the x-axis and the point specified by its arguments, interpreted as x and y coordinates.
Additionally, sinpi(x)
and cospi(x)
are provided for more accurate computations
of sin(pi*x)
and cos(pi*x)
respectively.
In order to compute trigonometric functions with degrees
instead of radians, suffix the function with d
. For example, sind(x)
computes the sine of x
where x
is specified in degrees.
The complete list of trigonometric functions with degree variants is:
sindcosdtandcotdsecdcscdasindacosdatandacotdasecdacscd
Special functions¶
Function | Description |
---|---|
erf(x) | error function at x |
erfc(x) | complementary error function, i.e. the accurate version of 1-erf(x) for large x |
erfinv(x) | inverse function to erf() |
erfcinv(x) | inverse function to erfc() |
erfi(x) | imaginary error function defined as -im*erf(x*im) , where im is the imaginary unit |
erfcx(x) | scaled complementary error function, i.e. accurate exp(x^2)*erfc(x) for large x |
dawson(x) | scaled imaginary error function, a.k.a. Dawson function, i.e. accurate exp(-x^2)*erfi(x)*sqrt(pi)/2 for large x |
gamma(x) | gamma function at x |
lgamma(x) | accurate log(gamma(x)) for large x |
lfact(x) | accurate log(factorial(x)) for large x ; same as lgamma(x+1) for x>1 , zero otherwise |
digamma(x) | digamma function (i.e. the derivative of lgamma() ) at x |
beta(x,y) | beta function at x,y |
lbeta(x,y) | accurate log(beta(x,y)) for large x or y |
eta(x) | Dirichlet eta function at x |
zeta(x) | Riemann zeta function at x |
airy(z) , airyai(z) , airy(0,z) | Airy Ai function at z |
airyprime(z) , airyaiprime(z) , airy(1,z) | derivative of the Airy Ai function at z |
airybi(z) , airy(2,z) | Airy Bi function at z |
airybiprime(z) , airy(3,z) | derivative of the Airy Bi function at z |
airyx(z) , airyx(k,z) | scaled Airy AI function and k th derivatives at z |
besselj(nu,z) | Bessel function of the first kind of order nu at z |
besselj0(z) | besselj(0,z) |
besselj1(z) | besselj(1,z) |
besseljx(nu,z) | scaled Bessel function of the first kind of order nu at z |
bessely(nu,z) | Bessel function of the second kind of order nu at z |
bessely0(z) | bessely(0,z) |
bessely1(z) | bessely(1,z) |
besselyx(nu,z) | scaled Bessel function of the second kind of order nu at z |
besselh(nu,k,z) | Bessel function of the third kind (a.k.a. Hankel function) of order nu at z ; k must be either 1 or 2 |
hankelh1(nu,z) | besselh(nu,1,z) |
hankelh1x(nu,z) | scaled besselh(nu,1,z) |
hankelh2(nu,z) | besselh(nu,2,z) |
hankelh2x(nu,z) | scaled besselh(nu,2,z) |
besseli(nu,z) | modified Bessel function of the first kind of order nu at z |
besselix(nu,z) | scaled modified Bessel function of the first kind of order nu at z |
besselk(nu,z) | modified Bessel function of the second kind of order nu at z |
besselkx(nu,z) | scaled modified Bessel function of the second kind of order nu at z |