Математические операции и элементарные функции
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 и наоборот |
Числовая константа, помещенная непосредственно перед идентификатором или скобками, например 2x или 2(x+y), обрабатывается как умножение, за исключением того, что имеет более высокий приоритет, чем другие бинарные операции. Подробности см. в разделе Коэффициенты числовых литералов.
Система повышения Julia делает арифметические операции над смешанными типами аргументов «просто работающими» естественным и автоматическим образом. Подробности о системе повышения см. в разделе Преобразование и повышение.
Вот несколько простых примеров использования арифметических операторов:
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) здесь для мотивации.
Побитовые операторы
Следующие побитовые операторы поддерживаются для всех примитивных целочисленных типов:
| Выражение | Название |
|---|---|
~x |
побитовое отрицание |
x & y |
побитовое И |
x | y |
побитовое ИЛИ |
x ⊻ y |
побитовое исключающее ИЛИ (XOR) |
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] |
| Синтаксис | : .. |
Слева направо |
| Синтаксис | |> |
Слева направо |
| Синтаксис | <| |
Справа налево |
| Сравнения | > < >= <= == === != !== <: |
Неассоциативные |
| Управление потоком |
&& и || и ?
|
Справа налево |
| Пара | => |
Справа налево |
| Присваивания | = += -= *= /= //= \= ^= ÷= %= |= &= ⊻= <<= >>= >>>= |
Справа налево |
Полный список всех операторов Julia и их приоритетов см. в начале этого файла: src/julia-parser.scm
Коэффициенты числовых литералов, например, 2x, обрабатываются как умножения с более высоким приоритетом, чем любая другая бинарная операция, а также имеют более высокий приоритет, чем ^.
Вы также можете получить числовой приоритет любого оператора с помощью встроенной функции 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(:(=)) # (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) |
деление с округлением вниз; частное округляется к -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) |
модуль относительно 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) |
экспоненциальная функция натурального логарифма в 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.
-
1Унарные операторы
+и-требуют явных скобок вокруг своего аргумента, чтобы отличить их от оператора++, и т. д. Другие комбинации унарных операторов разбираются с правой ассоциативностью, например,√√-aкак√(√(-a)). -
2Операторы
+,++и*неассоциативны.a + b + cразбирается как+(a, b, c), а не как+(+(a, b), c). Однако методы по умолчанию для+(a, b, c, d...)и*(a, b, c, d...)оба по умолчанию используют левую ассоциативную оценку.
© 2009–2020 Jeff Bezanson, Stefan Karpinski, Viral B. Shah, and other contributors
Licensed under the MIT License.
https://docs.julialang.org/en/v1.5.3/manual/mathematical-operations/