Математические операции и элементарные функции
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(Int8, 3.14) Stacktrace: [...] julia> Int8(128.0) ERROR: InexactError: Int8(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) |
деление с округлением вверх; частное округляется к +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) |
указывает, установлен ли бит знака (истина) или сброшен (ложь) |
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.
© 2009–2019 Jeff Bezanson, Stefan Karpinski, Viral B. Shah, and other contributors
Licensed under the MIT License.
https://docs.julialang.org/en/v0.7.0/manual/mathematical-operations/