数学运算和基本函数

Julia 为它所有的基础数值类型,提供了整套的基础算术和位运算,也提供了一套高效、可移植的标准数学函数。

算术运算符

下面的 算术运算符 适用于所有的基本数值类型:

表达式 名称 描述
+x 一元加法 x 本身
-x 一元减法 相反数
x + y 二元加法 做加法
x - y 二元减法 做减法
x * y 乘法 做乘法
x / y 除法 做除法
x \ y 反除 等价于 y / x
x ^ y 乘方 xy 次幂
x % y 取余 等价于 rem(x, y)

以及 Bool 类型的非运算:

表达式 名称 描述
!x truefalse 互换

Julia 的类型提升系统使得参数类型混杂的算术运算也很简单自然。详见 类型转换和类型提升

算术运算的例子:

julia> 1 + 2 + 3
6

julia> 1 - 2
-1

julia> 3*2/12
0.5

(习惯上,优先级低的运算,前后多补些空格。这不是强制的。)

位运算符

下面的 位运算符 适用于所有整数类型:

Expression Name
~x 按位取反
x & y 按位与
x | y 按位或
x $ y 按位异或
x >>> y 向右 逻辑移位 (高位补 0 )
x >> y 向右 算术移位 (复制原高位)
x << y 向左逻辑/算术移位

位运算的例子:

julia> ~123
-124

julia> 123 & 234
106

julia> 123 | 234
251

julia> 123 $ 234
145

julia> ~uint32(123)
0xffffff84

julia> ~uint8(123)
0x84

复合赋值运算符

二元算术和位运算都有对应的复合赋值运算符,即运算的结果将会被赋值给左操作数。在操作符的后面直接加上 = 就组成了复合赋值运算符。例如, x += 3 相当于 x = x + 3

julia> x = 1
1

julia> x += 3
4

julia> x
4

复合赋值运算符有:

+=  -=  *=  /=  \=  %=  ^=  &=  |=  $=  >>>=  >>=  <<=

数值比较

所有的基础数值类型都可以使用比较运算符:

运算符 名称
== 等于
!= 不等于
< 小于
<= 小于等于
> 大于
>= 大于等于

一些例子:

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

整数是按位比较的。浮点数是按 IEEE 754 标准 比较的:

  • 有限数按照正常方式做比较.
  • 正数的零等于但不大于负数的零.
  • Inf 等于它本身,并且大于所有数, 除了 NaN.
  • -Inf 等于它本身,并且小于所有数, 除了 NaN.
  • NaN 不等于、不大于、不小于任何数,包括它本身.

上面最后一条是关于 NaN 的性质,值得留意:

julia> NaN == NaN
false

julia> NaN != NaN
true

julia> NaN < NaN
false

julia> NaN > NaN
false

NaN矩阵 中使用时会带来些麻烦:

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

Julia 提供了附加函数, 用以测试这些特殊值,它们使用哈希值来比较:

函数 测试
isequal(x, y) x 是否等价于 y
isfinite(x) x 是否为有限的数
isinf(x) x 是否为无限的数
isnan(x) x 是否不是数

isequal 函数,认为 NaN 等于它本身:

julia> isequal(NaN,NaN)
true

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

julia> isequal(NaN,NaN32)
true

isequal 也可以用来区分有符号的零:

julia> -0.0 == 0.0
true

julia> isequal(-0.0, 0.0)
false

链式比较

与大多数语言不同,Julia 支持 Python链式比较

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

对标量的比较,链式比较使用 && 运算符;对逐元素的比较使用 & 运算符,此运算符也可用于数组。例如, 0 .< A .< 1 的结果是一个对应的布尔数组,满足条件的元素返回 true 。

操作符 .< 是特别针对数组的; 只有当 AB 有着相同的大小时, A .< B 才是合法的. 比较的结果是布尔型数组, 其大小同 AB 相同. 这样的操作符被称为 按元素 操作符; Julia 提供了一整套的按元素操 作符: .*, .+, 等等. 有的按元素操作符也可以接受纯量, 例如上一段 的 0 .< A .< B. 这种表示法的意思是, 相应的纯量操作符会被施加到每一 个元素上去.

注意链式比较的比较顺序:

v(x) = (println(x); x)

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

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

中间的值只计算了一次,而不是像 v(1) < v(2) && v(2) <= v(3) 一样计算了两次。但是,链式比较的计算顺序是不确定的。不要在链式比较中使用带副作用(比如打印)的表达式。如果需要使用副作用表达式,推荐使用短路 && 运算符(详见 短路求值 )。

运算优先级

Julia 运算优先级从高至低依次为:

类型 运算符
语法 . followed by ::
^ and its elementwise equivalent .^
分数 // and .//
乘除 * / % & \ and .* ./ .% .\
位移 << >> >>> and .<< .>> .>>>
加减 + - | $ and .+ .-
语法 : .. followed by |>
比较 > < >= <= == === != !== <: and .> .< .>= .<= .== .!=
逻辑 && followed by || followed by ?
赋值 = += -= *= /= //= \= ^= %= |= &= $= <<= >>= >>>=.+= .-= .*= ./= .//= .\= .^= .%=

基本函数

Julia 提供了一系列数学函数和运算符:

舍入函数

函数 描述 返回类型
round(x) x 舍入到最近的整数 FloatingPoint
iround(x) x 舍入到最近的整数 Integer
floor(x) x-Inf 取整 FloatingPoint
ifloor(x) x-Inf 取整 Integer
ceil(x) x+Inf 取整 FloatingPoint
iceil(x) x+Inf 取整 Integer
trunc(x) x 向 0 取整 FloatingPoint
itrunc(x) x 向 0 取整 Integer

除法函数

函数 描述
div(x,y) 截断取整除法;商向 0 舍入
fld(x,y) 向下取整除法;商向 -Inf 舍入
cld(x,y) 向上取整除法; 商向 +Inf 舍入
rem(x,y) 除法余数;满足 x == div(x,y)*y + rem(x,y) ,与 x 同号
divrem(x,y) 返回 (div(x,y),rem(x,y))
mod(x,y) 取模余数;满足 x == fld(x,y)*y + mod(x,y) ,与 y 同号
mod2pi(x) 对 2pi 取模余数; 0 <= mod2pi(x)  < 2pi
gcd(x,y...) x, y, ... 的最大公约数,与 x 同号
lcm(x,y...) x, y, ... 的最小公倍数,与 x 同号

符号函数和绝对值函数

函数 描述
abs(x) x 的幅值
abs2(x) x 的幅值的平方
sign(x) x 的正负号,返回值为 -1, 0, 或 +1
signbit(x) 是否有符号位,有 (true) 或者 无 (false)
copysign(x,y) 返回一个数,它具有 x 的幅值, y 的符号位
flipsign(x,y) 返回一个数,它具有 x 的幅值, x*y 的符号位

乘方,对数和开方

函数 描述
sqrt(x) √x x 的平方根
cbrt(x) ∛x x 的立方根
hypot(x,y) 误差较小的 sqrt(x^2 + y^2)
exp(x) 自然指数 ex 次幂
expm1(x) x 接近 0 时,精确计算 exp(x)-1
ldexp(x,n) n 为整数时,高效计算``x*2^n``
log(x) x 的自然对数
log(b,x) b 为底 x 的对数
log2(x) 以 2 为底 x 的对数
log10(x) 以 10 为底 x 的对数
log1p(x) x 接近 0 时,精确计算 log(1+x)
exponent(x) trunc(log2(x))
significand(x) returns the binary significand (a.k.a. mantissa) of a floating-point number x

为什么要有 hypot, expm1, log1p 等函数,参见 John D. Cook 的博客: expm1, log1p, erfchypot

三角函数和双曲函数

Julia 内置了所有的标准三角函数和双曲函数

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   atan2

除了 atan2 之外,都是单参数函数。 atan2 给出了 x 轴,与由 xy 确定的点之间的 弧度

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

如果想要以度,而非弧度,为单位计算三角函数,应使用带 d 后缀的函数。例如, sind(x) 计算 x 的正弦值,这里 x 的单位是度。以下的列表是全部的以度为单位的三角函数:

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

特殊函数

函数 描述
erf(x) x 处的 误差函数
erfc(x) 补误差函数。当 x 较大时,精确计算 1-erf(x)
erfinv(x) erf 的反函数
erfcinv(x) erfc 的反函数
erfi(x) the imaginary error function defined as -im * erf(x * im), where im is the imaginary unit
erfcx(x) the scaled complementary error function, i.e. accurate exp(x^2) * erfc(x) for large x
dawson(x) the 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) x 处的 gamma 函数
lgamma(x) x 较大时,精确计算 log(gamma(x))
lfact(x) accurate log(factorial(x)) for large x; same as lgamma(x+1) for x > 1, zero otherwise
digamma(x) the digamma function (i.e. the derivative of lgamma) at x
beta(x,y) the beta function at x,y
lbeta(x,y) accurate log(beta(x,y)) for large x or y
eta(x) the Dirichlet eta function at x
zeta(x) the Riemann zeta function at x
airy(z), airyai(z), airy(0,z) the Airy Ai function at z
airyprime(z), airyaiprime(z), airy(1,z) Airy Ai 函数在 z 处的导数
airybi(z), airy(2,z) the Airy Bi function at z
airybiprime(z), airy(3,z) Airy Bi 函数在 z 处的导数
airyx(z), airyx(k,z) the scaled Airy AI function and k th derivatives at z
besselj(nu,z) the Bessel function of the first kind of order nu at z
besselj0(z) besselj(0,z)
besselj1(z) besselj(1,z)
besseljx(nu,z) the scaled Bessel function of the first kind of order nu at z
bessely(nu,z) the Bessel function of the second kind of order nu at z
bessely0(z) bessely(0,z)
bessely1(z) bessely(1,z)
besselyx(nu,z) the scaled Bessel function of the second kind of order nu at z
besselh(nu,k,z) the 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) the modified Bessel function of the first kind of order nu at z
besselix(nu,z) the scaled modified Bessel function of the first kind of order nu at z
besselk(nu,z) the modified Bessel function of the second kind of order nu at z
besselkx(nu,z) the scaled modified Bessel function of the second kind of order nu at z