about_Arithmetic_Operators

Краткое описание

Описывает операторы, выполняющие арифметику в PowerShell.

Подробное описание

Арифметические операторы вычисляют числовые значения. Вы можете использовать один или несколько арифметических операторов для добавления, вычитания, умножения и деления значений, а также для вычисления остальных (модул) операции деления.

Оператор сложения (+) и оператор умножения (*) также работает с строками, массивами и хэш-файлами. Оператор сложения объединяет входные данные. Оператор умножения возвращает несколько копий входных данных. Можно даже смешивать типы объектов в арифметической инструкции. Метод, используемый для вычисления инструкции, определяется типом самого левого объекта в выражении.

Начиная с PowerShell 2.0 все арифметические операторы работают на 64-разрядных числах.

Начиная с PowerShell 3.0, -shr добавляются (shift-right) и -shl (shift-left) для поддержки битовой арифметики в PowerShell. Побитовые операторы работают только над целыми типами.

PowerShell поддерживает следующие арифметические операторы:

  • Добавление (+) — добавляет числа, сцепляет строки, массивы и хэш-таблицы

    6 + 2                        # result = 8
    "file" + "name"              # result = "filename"
    @(1, "one") + @(2.0, "two")  # result = @(1, "one", 2.0, "two")
    @{"one" = 1} + @{"two" = 2}  # result = @{"one" = 1; "two" = 2}
    
  • Вычитание (-) — вычитание или отрицание чисел

    6 - 2   # result = 4
    - -6    # result = 6
    (Get-Date).AddDays(-1) # Yesterday's date
    
  • Умножение (*) — умножение чисел или копирование строк и массивов указанного количества раз

    6 * 2       # result = 12
    @("!") * 4  # result = @("!","!","!","!")
    "!" * 3     # result = "!!!"
    
  • Деление (/) — делит числа

    6 / 2  # result = 3
    
  • Модуль (%) — возвращает оставшуюся часть операции деления.

    7 % 2  # result = 1
    
  • Битовое И (-band)

    5 -band 3  # result = 1
    
  • Битовая НЕ (-bnot)

    -bnot 5  # result = -6
    
  • Битовое ИЛИ (-bor)

    5 -bor 0x03  # result = 7
    
  • Битовая XOR (-bxor)

    5 -bxor 3   # result = 6
    
  • Сдвиг битов влево (-shl)

    102 -shl 2  # result = 408
    
  • Сдвигает биты вправо (-shr)

    102 -shr 2  # result = 25
    

Приоритет операторов

PowerShell обрабатывает арифметические операторы в следующем порядке:

Приоритет Operator Description
1 () Круглые скобки
2 - Для отрицательного числа или унарного оператора
3 *, , /% Для умножения и деления
4 +, - Для добавления и вычитания
5 -band, -bnot Для побитовых операций
5 -bor, -bxor Для побитовых операций
5 -shr, -shl Для побитовых операций

PowerShell обрабатывает выражения слева направо в соответствии с правилами приоритета. В следующих примерах показан эффект правил приоритета:

3+6/3*4    # result = 11
3+6/(3*4)  # result = 3.5
(3+6)/3*4  # result = 12

Порядок оценки выражений PowerShell может отличаться от других языков программирования и скриптов, используемых вами. В следующем примере показана сложная инструкция назначения.

$a = 0
$b = @(1,2)
$c = @(-1,-2)

$b[$a] = $c[$a++]

В этом примере выражение $a++ вычисляется до $b[$a]. Вычисление $a++ изменений значения $a после его использования в инструкции $c[$a++], но прежде чем он используется в $b[$a]. Переменная $a в $b[$a] равном 1, а не 0. Поэтому оператор присваивает значение $b[1], а не $b[0].

Приведенный выше код эквивалентен следующему:

$a = 0
$b = @(1,2)
$c = @(-1,-2)

$tmp = $c[$a]
$a = $a + 1
$b[$a] = $tmp

Разделение и округление

Если кворот операции деления является целым числом, PowerShell округляет значение до ближайшего целого числа. Если значение равно .5, оно округляется до ближайшего даже целого числа.

В следующем примере показан эффект округления до ближайшего даже целого числа.

PS> [int]( 5 / 2 )  # Result is rounded down
2

PS> [int]( 7 / 2 )  # Result is rounded up
4

Класс можно использовать [Math] для получения разного поведения округления.

PS> [int][Math]::Round(5 / 2,[MidpointRounding]::AwayFromZero)
3

PS> [int][Math]::Ceiling(5 / 2)
3

PS> [int][Math]::Floor(5 / 2)
2

Дополнительные сведения см. в методе Math.Round .

Преобразование типов в соответствии с результатом

PowerShell автоматически выбирает числовой тип .NET, который лучше всего выражает результат без потери точности. Например:

2 + 3.1
(2).GetType().FullName
(2 + 3.1).GetType().FullName
5.1
System.Int32
System.Double

Если результат операции слишком велик для типа, тип результата расширяется для размещения результата, как показано в следующем примере:

(512MB).GetType().FullName
(512MB * 512MB).GetType().FullName
System.Int32
System.Double

Тип результата не всегда совпадает с одним из операндов. В следующем примере отрицательное значение не может быть приведение к целому чиселу без знака, а целое число без знака слишком велико для приведения Int32к:

([int32]::minvalue + [uint32]::maxvalue).gettype().fullname
System.Int64

В этом примере Int64 можно разместить оба типа.

Тип System.Decimal является исключением. Если любой операнд имеет десятичный тип, результатом является десятичный тип. Любой результат слишком большой для десятичного значения является ошибкой.

PS> [Decimal]::maxvalue
79228162514264337593543950335

PS> [Decimal]::maxvalue + 1
RuntimeException: Value was either too large or too small for a Decimal.

Потенциальная потеря точности

В любой момент, когда у вас есть результат, превышающий диапазон типа, вы рискуете потерять точность из-за преобразования типов. Например, добавление достаточно большого [long] размера и [int] приводит к преобразованию [double]операндов в . В этом примере 9223372036854775807 является максимальное значение целого [long] числа. Добавление к значению переполнено диапазоном [long].

PS> (9223372036854775807 + 2).GetType().FullName
System.Double

Приведение результата к получению [ulong] неточного результата, потому что операнды были принудились к первому [double] .

PS> [ulong](9223372036854775807 + 2)
9223372036854775808

Определение большего значения в первую очередь [ulong] избегает проблемы и создает правильный результат.

PS> 9223372036854775807ul + 2
9223372036854775809

Однако превышение диапазона [ulong] результатов [double].

PS> ([ulong]::MaxValue + 1).GetType().FullName
System.Double

Арифметика Bigint

При выполнении арифметических операций с [bigint] числами [bigint]PowerShell преобразует все операнды в , что приводит к усечению не целых значений. Например, [double] значение 1.9 усечено до 1 момента преобразования [bigint]в .

PS> [bigint]1 / 1.9
1
PS> 1 / [bigint]1.9
1

Это поведение отличается от поведения других числовых типов. В этом примере разделено [int] на [double] результаты [double]. 1.9 Приведение к [int] округляет значение до 2.

PS> 1 / 1.9
0.526315789473684
PS> 1 / [int]1.9
0.5

Добавление и умножение нечисловых типов

Можно добавлять числа, строки, массивы и хэш-таблицы. Кроме того, можно умножить числа, строки и массивы. Однако вы не можете умножить хэш-таблицы.

При добавлении строк, массивов или хэш-таблиц элементы объединяются. При объединение коллекций, таких как массивы или хэш-таблицы, создается новый объект, содержащий объекты из обеих коллекций. Если попытаться объединить хэш-таблицы с одинаковым ключом, операция завершается ошибкой.

Например, следующие команды создают два массива и добавляют их:

$a = 1,2,3
$b = "A","B","C"
$a + $b
1
2
3
A
B
C

Вы также можете выполнять арифметические операции с объектами разных типов. Операция, выполняемая PowerShell, определяется типом Microsoft .NET самого левого объекта в операции. PowerShell пытается преобразовать все объекты в операцию в тип .NET первого объекта. Если он успешно преобразует объекты, он выполняет операцию, соответствующую типу .NET первого объекта. Если не удается преобразовать любой из объектов, операция завершается ошибкой.

В следующих примерах демонстрируется использование операторов сложения и умножения в операциях, включающих различные типы объектов.

$array = 1,2,3
$red = [ConsoleColor]::Red
$blue = [ConsoleColor]::Blue

"file" + 16      # result = "file16"
$array + 16      # result = 1,2,3,16
$array + "file"  # result = 1,2,3,"file"
$array * 2       # result = 1,2,3,1,2,3
"file" * 3       # result = "filefilefile"
$blue + 3        # result = Red
$red - 3         # result = Blue
$blue - $red     # result = -3
+ '123'          # result = 123

Так как метод, используемый для вычисления инструкций, определяется самым левым объектом, добавлением и умножением в PowerShell не является строго коммутативным. Например, (a + b) не всегда равно (b + a)и (ab) не всегда равно (ba).

В следующих примерах демонстрируется этот принцип:

PS> "file" + 16
file16

PS> 16 + "file"
InvalidArgument: can't convert value "file" to type "System.Int32". Error:
"Input string wasn't in a correct format."

Хэш-таблицы немного отличаются. Вы можете добавить хэш-таблицы в другую хэш-таблицу, если добавленные хэш-таблицы не имеют повторяющихся ключей.

В следующем примере показано, как добавить хэш-таблицы друг к другу.

$hash1 = @{a=1; b=2; c=3}
$hash2 = @{c1="Server01"; c2="Server02"}
$hash1 + $hash2
Name                           Value
----                           -----
c2                             Server02
a                              1
b                              2
c1                             Server01
c                              3

В следующем примере возникает ошибка, так как один из ключей дублируется в обеих хэш-таблицах.

$hash1 = @{a=1; b=2; c=3}
$hash2 = @{c1="Server01"; c="Server02"}
$hash1 + $hash2
OperationStopped:
Line |
   3 |  $hash1 + $hash2
     |  ~~~~~~~~~~~~~~~
     | Item has already been added. Key in dictionary: 'c'  Key being added: 'c'

Кроме того, можно добавить хэш-таблицу в массив; и вся хэш-таблица становится элементом в массиве.

$array1 = @(0, "Hello World", [datetime]::Now)
$hash1 = @{a=1; b=2}
$array2 = $array1 + $hash1
$array2
0
Hello World

Monday, June 12, 2017 3:05:46 PM

Key   : a
Value : 1
Name  : a

Key   : b
Value : 2
Name  : b

Однако вы не можете добавить другой тип в хэш-таблицу.

$hash1 + 2
InvalidOperation: A hash table can only be added to another hash table.

Хотя операторы добавления очень полезны, используйте операторы назначения для добавления элементов в хэш-таблицы и массивы. Дополнительные сведения см. в about_assignment_operators. В следующих примерах оператор назначения используется += для добавления элементов в массив:

$array = @()
(0..2).foreach{ $array += $_ }
$array
0
1
2

Арифметические операторы и переменные

Также можно использовать арифметические операторы с переменными. Операторы действуют по значениям переменных. В следующих примерах показано использование арифметических операторов с переменными:

PS> $intA = 6
PS> $intB = 4
PS> $intA + $intB
10

PS> $a = "Power"
PS> $b = "Shell"
PS> $a + $b
PowerShell

Арифметические операторы и команды

Как правило, используются арифметические операторы в выражениях с числами, строками и массивами. Однако можно также использовать арифметические операторы с объектами, которые возвращаются и с свойствами этих объектов.

В следующих примерах показано, как использовать арифметические операторы в выражениях с командами PowerShell:

(Get-Date) + (New-TimeSpan -day 1)

Оператор круглых скобок принудительно выполняет оценку командлета Get-Date и оценку выражения командлета New-TimeSpan -Day 1 в этом порядке. Затем оба результата добавляются с помощью + оператора.

Get-Process | Where-Object { ($_.ws * 2) -gt 50mb }
Handles  NPM(K)    PM(K)      WS(K) VM(M)   CPU(s)     Id ProcessName
-------  ------    -----      ----- -----   ------     -- -----------
   1896      39    50968      30620   264 1,572.55   1104 explorer
  12802      78   188468      81032   753 3,676.39   5676 OUTLOOK
    660       9    36168      26956   143    12.20    988 PowerShell
    561      14     6592      28144   110 1,010.09    496 services
   3476      80    34664      26092   234 ...45.69    876 svchost
    967      30    58804      59496   416   930.97   2508 WINWORD

В приведенном выше выражении каждое рабочее пространство$_.ws процесса умножается на 2; и, по сравнению с 50mb результатом, чтобы узнать, больше ли это.

битовые операторы;

PowerShell поддерживает стандартные побитовые операторы, включая побитовые и (-band) инклюзивные и эксклюзивные побитовые операторы (и), а -bxorтакже побитовые операторы-bor NOT (-bnot).

Начиная с PowerShell 2.0, все побитовые операторы работают с 64-разрядными целыми числами.

Начиная с PowerShell 3.0, -shr в PowerShell вводятся (shift-right) и -shl (shift-left) для поддержки битовой арифметики в PowerShell.

PowerShell поддерживает следующие битовые операторы.

Operator Description Выражение Результат
-band Побитовое И 10 -band 3 2
-bor Битовое ИЛИ (включительно) 10 -bor 3 11
-bxor Побитовое ИЛИ (эксклюзивное) 10 -bxor 3 9
-bnot Побитовое НЕ -bNot 10 -11
-shl Тестирование 102 -shl 2 408
-shr Тестирование 102 -shr 1 51

Побитовые операторы действуют в двоичном формате значения. Например, битовая структура для числа 10 00001010 (на основе 1 байта), а битовая структура для числа 3 00000011. При использовании побитового оператора для сравнения от 10 до 3 отдельные биты в каждом байте сравниваются.

В битовой операции AND результирующий бит имеет значение 1, только если оба входных бита равны 1.

1010      (10)
0011      ( 3)
--------------  bAND
0010      ( 2)

В побитовой операции OR (включительно) результирующий бит имеет значение 1, если либо оба входных бита равны 1. В результирующем бите задано значение 0, только если оба входных бита имеют значение 0.

1010      (10)
0011      ( 3)
--------------  bOR (inclusive)
1011      (11)

В побитовой операции OR (эксклюзивный) результирующий бит имеет значение 1, только если один входной бит 1.

1010      (10)
0011      ( 3)
--------------  bXOR (exclusive)
1001      ( 9)

Побитовый оператор NOT — это унарный оператор, который создает двоичное дополнение значения. Для бита 1 задано значение 0, а для бита 0 задано значение 1.

Например, двоичное дополнение 0 равно -1, максимальное целое число без знака (0xFFFFFFFF), а двоичное дополнение -1 равно 0.

-bNot 10
-11
0000 0000 0000 1010  (10)
------------------------- bNOT
1111 1111 1111 0101  (-11, 0xFFFFFFF5)

В побитовой операции влево все биты перемещаются влево, где "n" является значением правого операнда. Нуль вставляется в то место.

Выражение Результат Двоичный результат
21 -shl 0 21 0001 0101
21 -shl 1 42 0010 1010
21 -shl 2 84 0101 0100

В побитовой операции сдвига вправо все биты перемещаются вправо, где "n" задается правым операндом. Оператор shift-right (-shr) копирует бит знака в левое место при перемещении подписанного значения. Для неподписанных значений нуль вставляется в левую позицию.

Выражение Результат Binary Hex
21 -shr 0 21 00010101 0x15
21 -shr 1 10 00001010 0x0A
21 -shr 2 5 00000101 0x05
21 -shr 31 0 00000000 0x00
21 -shr 32 21 00010101 0x15
21 -shr 64 21 00010101 0x15
21 -shr 65 10 00001010 0x0A
21 -shr 66 5 00000101 0x05
[int]::MaxValue -shr 1 1073741823 00111111111111111111111111111111 0x3FFFFFFF
[int]::MinValue -shr 1 -1073741824 11000000000000000000000000000000 0xC0000000
-1 -shr 1 -1 11111111111111111111111111111111 0xFFFFFFFF
(-21 -shr 1) -11 11111111111111111111111111110101 0xFFFFFFF5
(-21 -shr 2) -6 11111111111111111111111111111010 0xFFFFFFF4

См. также