数学运算和初等函数 · Julia中文文档

您所在的位置:网站首页 自然对数e的概念和意义是什么意思 数学运算和初等函数 · Julia中文文档

数学运算和初等函数 · Julia中文文档

2024-07-09 12:54| 来源: 网络整理| 查看: 265

 完善 Transifex 上的翻译数学运算和初等函数

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

算术运算符

以下算术运算符支持所有的原始数值类型:

表达式名称描述+x一元加法运算符全等操作-x一元减法运算符将值变为其相反数x + y二元加法运算符执行加法x - y二元减法运算符执行减法x * y乘法运算符执行乘法x / y除法运算符执行除法x ÷ y整除取 x / y 的整数部分x \ y反向除法等价于 y / xx ^ y幂操作符x 的 y 次幂x % y取余等价于 rem(x,y)

除了优先级比二元操作符高以外,直接放在标识符或括号前的数字,如 2x 或 2(x+y) 还会被视为乘法。详见数值字面量系数。

Julia 的类型提升系统使得混合参数类型上的代数运算也能顺其自然的工作,请参考类型提升系统来了解更多内容。

符号 ÷ 可以通过输入 \div 到 REPL 或 Julia IDE 的方式来打出. 更多信息参见 Unicode 输入表。

这里是使用算术运算符的一些简单例子:

julia> 1 + 2 + 3 6 julia> 1 - 2 -1 julia> 3*2/12 0.5

习惯上我们会把优先运算的操作符紧邻操作数,比如 -x + 2 表示先要给 x 取反,然后再加 2 。

在乘法操作中,false 被视作 零。

julia> NaN * false 0.0 julia> false * Inf 0.0

这在已知某些量为零时,可以避免 NaN 的传播。详细的动机参见:Knuth (1992)。

布尔运算符

Bool 类型支持以下布尔运算符:

表达式名称!x否定x && y短路与x || y短路或

否定将 true 更改为 false,反之亦然。链接页面上解释了逻辑短路。

请注意,Bool 是一个整数类型,所有常用的类型提升规则和数字运算符仍然对它适用。

位运算符

所有原始整数类型都支持以下位运算符:

表达式名称~x按位取反x & y按位与x | y按位或x ⊻ y按位异或(逻辑异或)x ⊼ y按位与(非与)x ⊽ y按位或(非或)x >>> y逻辑右移x >> y算术右移x ~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复合赋值运算符

每一个二元运算符和位运算符都可以给左操作数复合赋值:方法是把 = 直接放在二元运算符后面。比如,x += 3 等价于 x = x + 3 。

julia> x = 1 1 julia> x += 3 4 julia> x 4

二元运算符和位运算符的复合赋值操作符有下面几种:

+= -= *= /= \= ÷= %= ^= &= |= ⊻= >>>= >>= x *= 2 # 与 x = x * 2 相同 2 julia> typeof(x) Int64向量化 “点” 运算符

Julia 中,每个二元运算符都有一个 “点” 运算符与之对应,例如 ^ 就有对应的 .^ 存在。这个对应的 .^ 被 Julia 自动地定义为逐元素地执行 ^ 运算。比如 [1,2,3] ^ 3 是非法的,因为数学上没有给(长宽不一样的)数组的立方下过定义。但是 [1,2,3] .^ 3 在 Julia 里是合法的,它会逐元素地执行 ^ 运算(或称向量化运算),得到 [1^3, 2^3, 3^3]。类似地,! 或 √ 这样的一元运算符,也都有一个对应的 .√ 用于执行逐元素运算。

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

更确切地说,a .^b 被解析为 “点运算” 调用 (^).(a,b),这会执行 广播 操作:该操作能结合数组和标量、相同大小的数组(进行元素之间的运算),甚至不同形状的数组(例如行、列向量结合生成矩阵)。此外,就像所有向量化的点运算调用一样,这些点运算符是融合的。例如,在计算关于数组 A 的表达式 2 .* A.^2 .+ sin.(A)(或者等价地,使用@. 宏,@. 2A^2 + sin(A)),Julia 只对 A 进行做一次循环,遍历 A 中的每个元素 a 并计算 2a^2 + sin(a)。特别的,类似 f.(g.(x)) 的嵌套点运算调用也是融合的,并且“相邻的”二元运算符表达式 x .+ 3 .* x.^2 可以等价转换为嵌套 dot 调用:(+).(x, (*).(3, (^).(x, 2)))。

除了点运算符,我们还有逐点赋值运算符,类似 a .+= b(或者 @. a += b)会被解析成 a .= a .+ b,这里的 .= 是一个融合的 in-place 运算,更多信息请查看 dot 文档)。

这个点语法,也能用在用户自定义的运算符上。例如,通过定义 ⊗(A,B) = kron(A,B) 可以为 Kronecker 积(kron)提供一个方便的中缀语法 A ⊗ B,那么配合点语法 [A,B] .⊗ [C,D] 就等价于 [A⊗C, B⊗D]。

将点运算符用于数值字面量可能会导致歧义。例如,1.+x 到底是表示 1. + x 还是 1 .+ x?这会令人疑惑。因此不允许使用这种语法,遇到这种情况时,必须明确地用空格消除歧义。

数值比较

标准的比较操作对所有原始数值类型有定义:

操作符名称==相等!=, ≠不等大于>=, ≥大于等于

下面是一些简单的例子:

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 -1 3 < -0.5 false

整数的比较方式是标准的按位比较,而浮点数的比较方式则遵循 IEEE 754 标准。

有限数的大小顺序,和我们所熟知的相同。+0 等于但不大于 -0.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 给这些特别的数提供了下面几个额外的测试函数。这些函数在某些情况下很有用处,比如在做 hash 比较时。

函数测试是否满足如下性质isequal(x, y)x 与 y 是完全相同的isfinite(x)x 是有限大的数字isinf(x)x 是(正/负)无穷大isnan(x)x 是 NaN

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 在这个问题上做的是正确的。

对于其它类型,isequal 会默认调用 ==,所以如果你想给自己的类型定义相等,那么就只需要为 == 增加一个方法。如果你想定义一个你自己的相等函数,你可能需要定义一个对应的 hash 方法,用于确保 isequal(x,y) 隐含着 hash(x) == hash(y)。

链式比较

与其他多数语言不同,就像 notable exception of Python 一样,Julia 允许链式比较:

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

链式比较在写数值代码时特别方便,它使用 && 运算符比较标量,数组则用 & 进行按元素比较。比如,0 .< A .< 1 会得到一个 boolean 数组,如果 A 的元素都在 0 和 1 之间则数组元素就都是 true。

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

julia> v(x) = (println(x); x) v (generic function with 1 method) julia> v(1) < v(2) v(1) > v(2) >>左结合除法//左结合乘法* / % & \ ÷左结合[2]加法+ - | ⊻左结合[2]语法: ..左结合语法|>左结合语法 < >= >>=右结合

想查看 每个 Julia 运算符的优先级,可以参考这个文件:src/julia-parser.scm。注意到有一些运算符在 Base 模块中没有定义但是可能是在标准库、包或者用户代码中定义的。

你也可以通过内置函数 Base.operator_precedence 查看任何给定运算符的优先级数值,数值越大优先级越高:

julia> Base.operator_precedence(:+), Base.operator_precedence(:*), Base.operator_precedence(:.) (11, 12, 17) julia> Base.operator_precedence(:sin), Base.operator_precedence(:+=), Base.operator_precedence(:(=)) # (注意:等号前后必须有括号 `:(=)`) (0, 1, 1)

另外,内置函数 Base.operator_associativity 可以返回运算符结合性的符号表示:

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)

注意诸如 :sin 这样的符号返回优先级 0,此值代表无效的运算符或非最低优先级运算符。类似地,它们的结合性被认为是 :none。

数字字面量系数,例如 2x 被视为比任何其他二元运算具有更高优先级的乘法,除了^,指数计算具有更高的优先级。

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

并列解析就像一元运算符,它在指数周围具有相同的自然不对称性:-x^y 和 2x^y解析为 -(x^y) 和 2(x^y) 而 x^-y 和 x^2y 解析为x^(-y) 和 x^(2y)。

数值转换

Julia 支持三种数值转换,它们在处理不精确转换上有所不同。

T(x) 和 convert(T,x) 都会把 x 转换为 T类型。

如果 T 是浮点类型,转换的结果就是最近的可表示值, 可能会是正负无穷大。如果 T 为整数类型,当 x 不能由 T 类型表示时,会抛出 InexactError。

x % T 将整数 x 转换为整型 T,与 x 模 2^n 的结果一致,其中 n 是 T 的位数。换句话说,在二进制表示下被截掉了一部分。

舍入函数 接收一个 T 类型的可选参数。比如,round(Int,x) 是 Int(round(x)) 的简写版。

下面的例子展示了不同的形式

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: trunc(Int8, 128.0) Stacktrace: [...]

请参考类型转换与类型提升一节来定义你自己的类型转换和提升规则。

舍入函数函数描述返回类型round(x)x 舍到最接近的整数typeof(x)round(T, x)x 舍到最接近的整数Tfloor(x)x 向 -Inf 舍入typeof(x)floor(T, x)x 向 -Inf 舍入Tceil(x)x 向 +Inf 方向取整typeof(x)ceil(T, x)x 向 +Inf 方向取整Ttrunc(x)x 向 0 取整typeof(x)trunc(T, x)x 向 0 取整T除法函数函数描述div(x,y), x÷y截断除法;商向零近似fld(x,y)向下取整除法;商向 -Inf 近似cld(x,y)向上取整除法;商向 +Inf 近似rem(x,y)取余;满足 x == div(x,y)*y + rem(x,y);符号与 x 一致mod(x,y)取模;满足 x == fld(x,y)*y + mod(x,y);符号与 y 一致mod1(x,y)偏移 1 的 mod;若 y>0,则返回 r∈(0,y],若 y


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3