Spec-Zone.ru › Julia 1.2

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

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]
Синтаксис : .. Слева направо
Синтаксис |> Слева направо
Синтаксис <| Справа налево
Сравнения > < >= <= == === != !== <: Не ассоциативны
Управление потоком && и || и ? Справа налево
Пара => Справа налево
Присваивания = += -= *= /= //= \= ^= ÷= %= |= &= ⊻= <<= >>= >>>= Справа налево
[1]

Унарные операторы + и - требуют явных скобок вокруг своего аргумента, чтобы отличить их от оператора ++, и т. д. Другие сочетания унарных операторов разбираются с правоассоциативностью, например, √√-a как √(√(-a)).

[2]

Операторы +, ++ и * не ассоциативны. 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(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) целочисленное деление; частное округляется к нулю
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) экспоненциальная функция по основанию e в точке 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/v1.2.0/manual/mathematical-operations/

Spec-Zone.ru

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