Математические операции и элементарные функции
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 добавляется к результату.)
Побитовые операторы
Следующие побитовые операторы поддерживаются для всех примитивных целочисленных типов:
| Выражение | Название |
|---|---|
~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 возвращает булевый массив, элементы которого истинны, если соответствующие элементы 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
Числовые коэффициенты литералов, например, 2x, обрабатываются как умножения с большей прецедентностью, чем любая другая бинарная операция, а также имеют большую прецедентность, чем ^.
Вы также можете найти числовую прецедентность любого заданного оператора с помощью встроенной функции 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— тип целого числа, генерируется исключение, если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) |
модуль относительно 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) |
точная экспоненциальная функция для 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) |
точная функция натурального логарифма для 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–2020 Jeff Bezanson, Stefan Karpinski, Viral B. Shah, and other contributors
Licensed under the MIT License.
https://docs.julialang.org/en/v1.3.1/manual/mathematical-operations/