Spec-Zone.ru › Julia 1.8

Математические операции и элементарные функции

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 делает арифметические операции на смешанных типах аргументов "простыми" и автоматическими. Подробности о системе повышения см. в разделе Преобразование и повышение.

Знак ÷ можно удобно ввести, написав \div<tab> в REPL или Julia IDE. Подробнее см. раздел руководства по вводу Юникода.

Вот несколько простых примеров с использованием арифметических операторов:

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 логический сдвиг вправо
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> nand(123, 123)
-124

julia> 123 ⊼ 123
-124

julia> nor(123, 124)
-128

julia> 123 ⊽ 124
-128

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 массива 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 в сторону -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%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–2022 Jeff Bezanson, Stefan Karpinski, Viral B. Shah, and other contributors
Licensed under the MIT License.
https://docs.julialang.org/en/v1.8/manual/mathematical-operations/

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API