贡献者: xzllxls
本文授权转载自郝林的 《Julia 编程基础》。原文链接:第 5 章 数值与运算。
Julia 预定义的复数类型是 Complex
。它是 Number
的直接子类型。为了构造出复数的虚部,Julia 还专门定义了一个常量 im
。这里的 im 是 imaginary 的缩写。它使用起来是这样的:
julia> 1 + 2im; typeof(1+2im)
Complex{Int64}
julia> 1.1 + 2.2im; typeof(1.1+2.2im)
Complex{Float64}
julia>
可以看到,Complex
是一个参数化的类型。因为在其名称的右侧还有一个由花括号包裹的类型参数。这个类型参数会是一个代表了某个类型的标识符。关于参数化类型,我们在下下一章就会讲到。
为了使常见的数学公式和表达式更加清晰,Julia 允许在变量之前紧挨一个数值字面量,以表示两个数相乘。比如,如果变量 x
的值是整数 8
,那么 2x^3
就表示 2
乘以 8
的 3
次方。又比如,2^3x
表示 2
的 24
次方。在这种情况下,变 x
就被称为数值字面量系数(numeric literal coefficient)。
正因为如此,我们才需要特别注意,上例中的 2im
和 2.2im
虽然看起来与这种表示法非常相似,但其含义却是完全不同的。整数或浮点数的字面量与常量 im
共同组成的是一个复数的虚部。而且还要注意,在构造复数的虚部时,我们就不能再使用数值字面量系数了。因为这肯定会产生歧义。比如,1 + 2xim
就是不合法的,除非已经存在一个名为 xim
的变量,但如此一来这表示的就不是一个复数了。如果必须有变量参与复数的构造,那么我们可以使用 complex
函数,例如:complex(1, 2x)
。
Julia 允许复数参与标准的数学运算。所以,下面的这些数学表达式是合法的:
julia> (1 + 2im) + (3 + 4im)
4 + 6im
julia> (1 + 2im) - (3 + 4im)
-2 - 2im
julia> (1 + 2im) * (3 + 4im)
-5 + 10im
julia> (1 + 2im) / (3 + 4im)
0.44 + 0.08im
julia> 3(1 + 2im)^8
-1581 + 1008im
julia>
例子中的圆括号代表着对运算次序的设定。这与它在数学中的一般含义是一致的。
要想分别得到一个复数的实部和虚部,我们就需要调用 real
函数和 imag
函数。示例如下:
julia> com1 = 1 + 2im
1 + 2im
julia> real(com1), imag(com1)
(1, 2)
julia>
另外,我们还可以利用、conj
函数求出一个复数的共轭(conjugate),以及使用 abs
函数计算出一个复数与 0
之间的距离,等等。总之,Julia 预定义的很多数学函数都可以应用于复数。
我们在前面说过,浮点数无法精确地表示所有小数。比如,1/3
是一个无限循环小数,但用浮点数表示的话只能是这样的:
julia> 1/3
0.3333333333333333
julia> typeof(ans)
Float64
julia>
严格来说,1/3
并不是一个浮点数。因为浮点数会对无限循环小数做舍入,这会损失精度。但是,它肯定是一个有理数。
在 Julia 中,有理数用于表示两个整数之间的精确比率。有理数的类型是 Rational
。它的值可以由操作符 //
来构造。代码如下:
julia> 1//3
1//3
julia> typeof(ans)
Rational{Int64}
julia>
在操作符 //
左侧的被称为分子,而在它右侧的被称为分母。注意,这两个数都只能是整数,而不能是浮点数。
如果在分子和分母之间存在公因数,那么 Julia 会自动地把它们化为最小项并让分母变为非负整数。例如:
julia> 3//9
1//3
julia> 3//-9
-1//3
julia> 42//126
1//3
julia>
函数 numerator
和 denominator
可以让我们分别得到一个有理数的分子和分母:
julia> rat1 = 1//3
1//3
julia> numerator(rat1)
1
julia> denominator(rat1)
3
julia>
有理数可以参与标准的数学运算。比如,我们可以拿一个有理数与一个整数、浮点数或者其他有理数进行比较。又比如,我们可以对有理数进行加减乘数等运算。另外,有理数也可以很容易地被转换为浮点数。例如:
julia> float(1//3)
0.3333333333333333
julia>
我在前面也说了,这实际上会存在精度上的损失。
最后,需要我们注意的是,0//0
是不合法的。该字面量会引发一个错误。相应的,表示浮点数的字面量 0/0
等同于 NaN
。从技术标准的角度讲,NaN
不与任何东西(包括它自己)相等。