Математические операции и элементарные функции
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)
|
Числовая литерал, размещенная непосредственно перед идентификатором или скобками, например, 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) для мотивации.
Булевы операторы
Следующие булевы операторы поддерживаются для типов Bool:
| Выражение | Название |
|---|---|
!x |
отрицание |
x && y |
короткое И |
x || y |
короткое ИЛИ |
Отрицание меняет true на false и наоборот. Операции короткого замыкания описаны на связанной странице.
Обратите внимание, что Bool — это целочисленный тип, и все обычные правила повышения типа и числовые операторы также определены для него.
Побитовые операторы
Следующие побитовые операторы поддерживаются для всех примитивных целочисленных типов:
| Выражение | Название |
|---|---|
~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 Vector{Int64}:
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. Обратите внимание, что некоторые операторы там не определены в модуле 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(:(=)) # (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.
Коэффициенты числовых литералов, например, 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— целочисленный тип, возникает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 вниз к ближайшему целому числу |
typeof(x) |
floor(T, x) |
округляет x вниз к ближайшему целому числу |
T |
ceil(x) |
округляет x вверх к ближайшему целому числу |
typeof(x) |
ceil(T, x) |
округляет x вверх к ближайшему целому числу |
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) |
модуль относительно 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) |
указывает, установлен ли бит знака (истина) или сброшен (ложь) |
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.
-
1Унарные операторы
+и-требуют явных скобок вокруг своего аргумента, чтобы отличить их от оператора++, и т. д. Другие композиции унарных операторов разбираются с правоассоциативностью, например,√√-aкак√(√(-a)). -
2Операторы
+,++и*являются неассоциативными.a + b + cразбирается как+(a, b, c), а не как+(+(a, b), c). Однако методы по умолчанию для+(a, b, c, d...)и*(a, b, c, d...)оба по умолчанию используют левоассоциативное вычисление.
© 2009–2021 Jeff Bezanson, Stefan Karpinski, Viral B. Shah, and other contributors
Licensed under the MIT License.
https://docs.julialang.org/en/v1.6.0/manual/mathematical-operations/