Математические операции и элементарные функции
Julia предоставляет полный набор основных арифметических и побитовых операторов для всех её числовых типов, а также эффективные реализации стандартных математических функций.
Арифметические операторы
Следующие арифметические операторы поддерживаются для всех числовых типов:
| Выражение | Название | Описание |
|---|---|---|
+x |
унарный плюс | тождественная операция |
-x |
унарный минус | отображает значения в их аддитивные обратные |
x + y |
бинарный плюс | выполняет сложение |
x - y |
бинарный минус | выполняет вычитание |
x * y |
умножение | выполняет умножение |
x / y |
деление | выполняет деление |
x ÷ y |
целочисленное деление | x / y, округлено до целого числа |
x \ y |
обратное деление | эквивалентно y / x
|
x ^ y |
возведение в степень | возводит x в y-ую степень |
x % y |
остаток от деления | эквивалентно rem(x,y)
|
а также отрицание для типов Bool:
| Выражение | Название | Описание |
|---|---|---|
!x |
отрицание | меняет true на false и наоборот |
Система повышения типа Julia делает арифметические операции над смешанными типами аргументов "простыми" и автоматическими. Подробнее о системе повышения типа см. Преобразование и повышение.
Ниже приведены несколько простых примеров с использованием арифметических операторов:
julia> 1 + 2 + 3 6 julia> 1 - 2 -1 julia> 3*2/12 0.5
(По соглашению, операторы обычно ставятся более компактно, если они применяются до других близлежащих операторов. Например, мы обычно пишем -x + 2 для отражения того, что сначала x отрицается, а затем 2 добавляется к результату.)
Побитовые операторы
Следующие побитовые операторы поддерживаются для всех типов целых чисел:
| Выражение | Название |
|---|---|
~x |
побитовое отрицание |
x & y |
побитовое И |
x | y |
побитовое ИЛИ |
x ⊻ y |
побитовое исключающее ИЛИ |
x >>> y |
логический сдвиг вправо |
x >> y |
арифметический сдвиг вправо |
x << y |
логический/арифметический сдвиг влево |
Ниже приведены примеры с побитовыми операторами:
julia> ~123 -124 julia> 123 & 234 106 julia> 123 | 234 251 julia> 123 ⊻ 234 145 julia> xor(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> x = 0x01; typeof(x) UInt8 julia> x *= 2 # Same as x = x * 2 2 julia> typeof(x) Int64
Векторизованные операторы "точка"
Для любой бинарной операции, такой как ^, существует соответствующая операция "точка" .^, которая автоматически определена для выполнения ^ поэлементно над массивами. Например, [1,2,3] ^ 3 не определена, так как нет стандартного математического смысла "возведения в куб" (не квадратного) массива, но [1,2,3] .^ 3 определена как вычисление поэлементного (или "векторизованного") результата [1^3, 2^3, 3^3]. Аналогично для унарных операторов, таких как ! или √, существует соответствующая операция .√, которая применяет оператор поэлементно.
julia> [1,2,3] .^ 3
3-element Array{Int64,1}:
1
8
27
Более конкретно, a .^ b анализируется как "вызов точки" (^).(a,b), который выполняет операцию векторного расширения: он может объединять массивы и скаляры, массивы одинакового размера (выполняя операцию поэлементно) и даже массивы разной формы (например, объединяя строку и столбец векторов для получения матрицы). Более того, как и все векторизованные "вызовы точки", эти "оператор точки" сливаются. Например, если вы вычислите 2 .* A.^2 .+ sin.(A) (или эквивалентно @. 2A^2 + sin(A), используя макрос @.) для массива A, он выполняет один цикл по A, вычисляя 2a^2 + sin(a) для каждого элемента A. В частности, вложенные вызовы точек, такие как f.(g.(x)) сливаются, а "смежные" бинарные операторы, такие как x .+ 3 .* x.^2 эквивалентны вложенным вызовам точек (+).(x, (*).(3, (^).(x, 2))).
Кроме того, "точечные" операторы обновления, такие как a .+= b (или @. a += b) анализируются как a .= a .+ b, где .= является объединённой операцией присваивания на месте (см. документацию синтаксиса точки).
Обратите внимание, что синтаксис точки также применим к пользовательским операторам. Например, если вы определите ⊗(A,B) = kron(A,B) для обеспечения удобного инфиксного синтаксиса A ⊗ B для произведений Кронекера (kron), то [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 true julia> -1 <= -1 true julia> -1 <= -2 false julia> 3 < -0.5 false
Целые числа сравниваются стандартным способом — путём сравнения битов. Вещественные числа сравниваются в соответствии со стандартом IEEE 754:
- Конечные числа упорядочены обычным образом.
- Положительное ноль равно, но не больше отрицательного нуля.
-
Infравно самому себе и больше всего остального, кромеNaN. -
-Infравно самому себе и меньше всего остального, кромеNaN. -
NaNне равно, не меньше и не больше ничего, включая себя.
Последний пункт потенциально удивителен и, следовательно, заслуживает упоминания:
julia> NaN == NaN false julia> NaN != NaN true julia> NaN < NaN false julia> NaN > NaN false
и может вызвать особые трудности с массивами:
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.
Для других типов isequal по умолчанию вызывает ==, поэтому если вы хотите определить равенство для своих типов, то вам нужно только добавить метод ==. Если вы определяете свою собственную функцию равенства, вы, вероятно, должны определить соответствующий метод hash, чтобы обеспечить, что isequal(x,y) подразумевает hash(x) == hash(y).
Цепочки сравнений
В отличие от большинства языков, за исключением Python, сравнения могут быть произвольно объединены в цепочки:
julia> 1 < 2 <= 2 < 3 == 3 > 2 >= 1 == 1 < 3 != 5 true
Цепочки сравнений часто очень удобны в числовом коде. Цепочки сравнений используют оператор && для скалярных сравнений и оператор & для поэлементных сравнений, что позволяет им работать с массивами. Например, 0 .< A .< 1 даёт булевый массив, чьи элементы равны true там, где соответствующие элементы A находятся между 0 и 1.
Обратите внимание на поведение цепочек сравнений:
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
Среднее выражение вычисляется только один раз, а не дважды, как это было бы, если бы выражение было записано как v(1) < v(2) && v(2) <= v(3). Однако порядок вычислений в цепочке сравнений не определен. Сильно рекомендуется не использовать выражения со побочными эффектами (например, вывод на печать) в цепочках сравнений. Если побочные эффекты необходимы, следует явно использовать оператор короткого замыкания && (см. оценку с короткой цепочкой).
Основные функции
Julia предоставляет обширную коллекцию математических функций и операторов. Эти математические операции определены для как можно более широкого класса числовых значений, включая целые числа, числа с плавающей запятой, рациональные и комплексные числа, где такие определения имеют смысл.
Кроме того, эти функции (как и любая функция Julia) могут применяться "векторизованным" способом к массивам и другим коллекциям с помощью символа точки f.(A), например, sin.(A) вычислит синус каждого элемента массива A.
Приоритет и ассоциативность операторов
Julia использует следующий порядок и ассоциативность операций, от наивысшего приоритета к наименьшему:
| Категория | Операторы | Ассоциативность |
|---|---|---|
| Синтаксис |
. и ::
|
Слева |
| Возведение в степень | ^ |
Справа |
| Унарные | + - √ |
Справа[1] |
| Битовые сдвиги | << >> >>> |
Слева |
| Дробные | // |
Слева |
| Умножение | * / % & \ ÷ |
Слева[2] |
| Сложение | + - | ⊻ |
Слева[2] |
| Синтаксис | : .. |
Слева |
| Синтаксис | |> |
Слева |
| Синтаксис | <| |
Справа |
| Сравнения | > < >= <= == === != !== <: |
Неассоциативно |
| Управление потоком |
&& и || и ?
|
Справа |
| Пара | => |
Справа |
| Присваивания | = += -= *= /= //= \= ^= ÷= %= |= &= ⊻= <<= >>= >>>= |
Справа |
Для унарных операторов + и - необходимо явно использовать скобки вокруг их аргумента, чтобы избежать неоднозначности с оператором ++, и т. д. Другие комбинации унарных операторов обрабатываются с правоассоциативностью, например, √√-a как √(√(-a)).
Операторы +, ++ и * неассоциативны. a + b + c интерпретируется как +(a, b, c), а не как +(+(a, b), c). Однако методы по умолчанию для +(a, b, c, d...) и *(a, b, c, d...) в обоих случаях по умолчанию применяют левоассоциативную оценку.
Полный список приоритетов всех операторов Julia см. в начале этого файла: src/julia-parser.scm
Вы также можете получить числовой приоритет любого данного оператора с помощью встроенной функции Base.operator_precedence, где более высокие значения имеют больший приоритет:
julia> Base.operator_precedence(:+), Base.operator_precedence(:*), Base.operator_precedence(:.) (11, 13, 17) julia> Base.operator_precedence(:sin), Base.operator_precedence(:+=), Base.operator_precedence(:(=)) # (Note the necessary parens on `:(=)`) (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.
Числовые преобразования
Julia поддерживает три формы числовых преобразований, которые различаются по обработке неточных преобразований.
-
Запись
T(x)илиconvert(T,x)преобразуетxв значение типаT.- Если
T— тип с плавающей запятой, результат — ближайшее представимое значение, которое может быть положительной или отрицательной бесконечностью. - Если
T— целочисленный тип, возникаетInexactError, еслиxне может быть представлено типомT.
- Если
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 до ближайшего целого |
T |
floor(x) |
округляет x в сторону -Inf
|
typeof(x) |
floor(T, x) |
округляет x в сторону -Inf
|
T |
ceil(x) |
округляет x в сторону +Inf
|
typeof(x) |
ceil(T, x) |
округляет x в сторону +Inf
|
T |
trunc(x) |
округляет x к нулю |
typeof(x) |
trunc(T, x) |
округляет x к нулю |
T |
Функции деления
| Функция | Описание |
|---|---|
div(x,y), x÷y
|
Целочисленное деление; частное округлено к нулю |
fld(x,y) |
Деление с округлением вниз; частное округлено к нулю |
cld(x,y) |
Деление с округлением вверх; частное округлено к нулю |
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) |
mod с смещением 1; возвращает r∈(0,y] для y>0 или r∈[y,0) для y<0, где mod(r, y) == mod(x, y)
|
mod2pi(x) |
Модуль относительно 2pi; 0 <= mod2pi(x) < 2pi
|
divrem(x,y) |
возвращает (div(x,y),rem(x,y))
|
fldmod(x,y) |
возвращает (fld(x,y),mod(x,y))
|
gcd(x,y...) |
наибольший общий делитель x, y,... |
lcm(x,y...) |
наименьшее общее кратное x, y,... |
Функции знака и абсолютного значения
| Функция | Описание |
|---|---|
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) |
гипотенуза прямоугольного треугольника с длинами сторон x и y
|
exp(x) |
экспонента по основанию e в точке x
|
expm1(x) |
точное значение exp(x)-1 для значений x близких к нулю |
ldexp(x,n) |
x*2^n эффективно вычисляется для целых значений n
|
log(x) |
натуральный логарифм от x
|
log(b,x) |
логарифм по основанию b от x
|
log2(x) |
логарифм по основанию 2 от x
|
log10(x) |
логарифм по основанию 10 от x
|
log1p(x) |
точное значение log(1+x) для значений x близких к нулю |
exponent(x) |
бинарный порядок (экспонента) числа x
|
significand(x) |
бинарная мантисса числа с плавающей запятой x
|
Для обзора причин необходимости и полезности функций, таких как hypot, expm1 и log1p, см. отличные записи в блоге Джона Д. Кука по этой теме: expm1, log1p, erfc и hypot.
Тригонометрические и гиперболические функции
Также определены все стандартные тригонометрические и гиперболические функции:
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
Все эти функции являются функциями одного аргумента, а atan также принимает два аргумента, соответствующие традиционной функции atan2.
Кроме того, sinpi(x) и cospi(x) обеспечивают более точные вычисления sin(pi*x) и cos(pi*x) соответственно.
Для вычисления тригонометрических функций в градусах вместо радиан, добавьте суффикс d. Например, sind(x) вычисляет синус угла x, где x задан в градусах. Полный список тригонометрических функций с вариантами для градусов:
sind cosd tand cotd secd cscd asind acosd atand acotd asecd acscd
Специальные функции
Многие другие специальные математические функции предоставляются пакетом SpecialFunctions.jl.
© 2009–2019 Jeff Bezanson, Stefan Karpinski, Viral B. Shah, and other contributors
Licensed under the MIT License.
https://docs.julialang.org/en/v1.1.1/manual/mathematical-operations/