Математические операции и элементарные функции
Julia предоставляет полный набор основных арифметических и побитовых операторов для всех числовых типов данных, а также эффективные реализации стандартных математических функций.
Арифметические операторы
Следующие арифметические операторы поддерживаются для всех числовых типов данных:
| Выражение | Имя | Описание |
|---|---|---|
+x |
унарный плюс | идентичная операция |
-x |
унарный минус | отображает значения в их аддитивные обратные |
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] без дополнительного программирования.
Числовые сравнения
Стандартные операторы сравнения определены для всех примитивных числовых типов:
| Оператор | Имя |
|---|---|
== |
равенство |
!=, ≠
|
неравенство |
< |
меньше |
<=, ≤
|
меньше или равно |
> |
больше |
>=, ≥
|
больше или равно |
Вот несколько простых примеров:
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 использует следующий порядок операций, от наивысшего к наименьшему приоритету:
| Категория | Операторы |
|---|---|
| Синтаксис |
. за которым следует ::
|
| Возведение в степень | ^ |
| Дробные выражения | // |
| Умножение | * / % & \ |
| Сдвиги битов | << >> >>> |
| Сложение | + - | ⊻ |
| Синтаксис |
: .. за которым следует |>
|
| Сравнения | > < >= <= == === != !== <: |
| Управление потоком |
&& за которым следует || за которым следует ?
|
| Присваивания | = += -= *= /= //= \= ^= ÷= %= |= &= ⊻= <<= >>= >>>= |
Полный список приоритетов всех операторов Julia см. в верхней части этого файла: src/julia-parser.scm
Вы также можете найти числовой приоритет любого данного оператора с помощью встроенной функции Base.operator_precedence, где более высокие числа имеют больший приоритет:
julia> Base.operator_precedence(:+), Base.operator_precedence(:*), Base.operator_precedence(:.) (9, 11, 15) julia> Base.operator_precedence(:+=), Base.operator_precedence(:(=)) # (Note the necessary parens on `:(=)`) (1, 1)
Числовые преобразования
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()
Stacktrace:
[1] Int8(::Int64) at ./sysimg.jl:77
julia> Int8(127.0)
127
julia> Int8(3.14)
ERROR: InexactError()
Stacktrace:
[1] convert(::Type{Int8}, ::Float64) at ./float.jl:658
[2] Int8(::Float64) at ./sysimg.jl:77
julia> Int8(128.0)
ERROR: InexactError()
Stacktrace:
[1] convert(::Type{Int8}, ::Float64) at ./float.jl:658
[2] Int8(::Float64) at ./sysimg.jl:77
julia> 127 % Int8
127
julia> 128 % Int8
-128
julia> round(Int8,127.4)
127
julia> round(Int8,127.6)
ERROR: InexactError()
Stacktrace:
[1] trunc(::Type{Int8}, ::Float64) at ./float.jl:651
[2] round(::Type{Int8}, ::Float64) at ./float.jl:337
См. Преобразование и продвижение для определения собственных преобразований и продвижения.
Функции округления
| Функция | Описание | Возвращаемый тип |
|---|---|---|
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) |
деление с усечением; частное округляется к нулю |
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) |
mod() со смещением 1; возвращает r∈(0,y] для y>0 или r∈[y,0) для y<0, где mod(r, y) == mod(x, y)
|
mod2pi(x) |
модуль по отношению к 2π; 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) |
экспоненциальная функция по основанию е в точке 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 atan2
Все они являются функциями с одним аргументом, за исключением atan2, которая возвращает угол в радианах между осью x и точкой, заданной её аргументами, интерпретируемыми как координаты x и y.
Кроме того, предоставляются 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
Специальные функции
| Функция | Описание |
|---|---|
gamma(x) |
гамма-функция в точке x
|
lgamma(x) |
точная log(gamma(x)) для больших x
|
lfact(x) |
точная log(factorial(x)) для больших x; совпадает с lgamma(x+1) для x > 1, в противном случае равно нулю |
beta(x,y) |
бета-функция в точке x,y
|
lbeta(x,y) |
точная log(beta(x,y)) для больших x или y
|
© 2009–2016 Jeff Bezanson, Stefan Karpinski, Viral B. Shah, and other contributors
Licensed under the MIT License.
https://docs.julialang.org/en/release-0.6/manual/mathematical-operations/