about_Arithmetic_Operators
Descrição breve
Descreve os operadores que executam aritmética no PowerShell.
Descrição longa
Os operadores aritméticos calculam valores numéricos. Você pode usar um ou mais operadores aritméticos para adicionar, subtrair, multiplicar e dividir valores e calcular o restante (módulo) de uma operação de divisão.
O operador de adição (+
) e o operador de multiplicação (*
) também operam em cadeias de caracteres, matrizes e tabelas de hash. O operador de adição concatena a entrada.
O operador de multiplicação retorna várias cópias da entrada. Você pode até mesmo misturar tipos de objeto em uma instrução aritmética. O método usado para avaliar a instrução é determinado pelo tipo do objeto mais à esquerda na expressão.
A partir do PowerShell 2.0, todos os operadores aritméticos funcionam em números de 64 bits.
A partir do PowerShell 3.0, os -shr
(shift-right) e -shl
(shift-left) são adicionados para dar suporte à aritmética bit a bit no PowerShell. Os operadores bit a bit só funcionam em tipos inteiros.
O PowerShell dá suporte aos seguintes operadores aritméticos:
Adição (
+
) – adiciona números, concatena cadeias de caracteres, matrizes e tabelas de hash6 + 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}
Subtração (
-
) – subtrai ou nega números6 - 2 # result = 4 - -6 # result = 6 (Get-Date).AddDays(-1) # Yesterday's date
Multiplicação (
*
) – Multiplique números ou copie cadeias de caracteres e matrizes o número de vezes especificado6 * 2 # result = 12 @("!") * 4 # result = @("!","!","!","!") "!" * 3 # result = "!!!"
Divisão (
/
) – divide números6 / 2 # result = 3
Módulo (
%
) – retorna o restante de uma operação de divisão.7 % 2 # result = 1
AND bit a bit (
-band
)5 -band 3 # result = 1
NOT bit a bit (
-bnot
)-bnot 5 # result = -6
OR bit a bit (
-bor
)5 -bor 0x03 # result = 7
XOR bit a bit (
-bxor
)5 -bxor 3 # result = 6
Desloca bits para a esquerda (
-shl
)102 -shl 2 # result = 408
Desloca bits para a direita (
-shr
)102 -shr 2 # result = 25
Precedência do operador
O PowerShell processa operadores aritméticos na seguinte ordem:
Precedência | Operador | Descrição |
---|---|---|
1 | () |
Parênteses |
2 | - |
Para um número negativo ou operador unário |
3 | * , / , % |
Para multiplicação e divisão |
4 | + , - |
Para adição e subtração |
5 | -band , -bnot |
Para operações bit a bit |
5 | -bor , -bxor |
Para operações bit a bit |
5 | -shr , -shl |
Para operações bit a bit |
O PowerShell processa as expressões da esquerda para a direita de acordo com as regras de precedência. Os exemplos a seguir mostram o efeito das regras de precedência:
3+6/3*4 # result = 11
3+6/(3*4) # result = 3.5
(3+6)/3*4 # result = 12
A ordem na qual o PowerShell avalia expressões pode ser diferente de outras linguagens de programação e script que você usou. O exemplo a seguir mostra uma instrução de atribuição complicada.
$a = 0
$b = @(1,2)
$c = @(-1,-2)
$b[$a] = $c[$a++]
Neste exemplo, a expressão $a++
é avaliada antes $b[$a]
de . A avaliação $a++
altera o valor de $a
depois que ele é usado na instrução $c[$a++]
, mas antes de ser usado em $b[$a]
. A variável $a
em $b[$a]
é igual a 1
, não 0
. Portanto, a instrução atribui um valor a $b[1]
, não $b[0]
a .
O código acima é equivalente a:
$a = 0
$b = @(1,2)
$c = @(-1,-2)
$tmp = $c[$a]
$a = $a + 1
$b[$a] = $tmp
Divisão e arredondamento
Quando o quociente de uma operação de divisão é um inteiro, o PowerShell arredonda o valor para o inteiro mais próximo. Quando o valor é .5
, ele arredonda para o inteiro par mais próximo.
O exemplo a seguir mostra o efeito do arredondamento para o inteiro par mais próximo.
PS> [int]( 5 / 2 ) # Result is rounded down
2
PS> [int]( 7 / 2 ) # Result is rounded up
4
Você pode usar a [Math]
classe para obter um comportamento de arredondamento diferente.
PS> [int][Math]::Round(5 / 2,[MidpointRounding]::AwayFromZero)
3
PS> [int][Math]::Ceiling(5 / 2)
3
PS> [int][Math]::Floor(5 / 2)
2
Para obter mais informações, consulte o método Math.Round .
Conversão de tipo para acomodar o resultado
O PowerShell seleciona automaticamente o tipo numérico do .NET que melhor expressa o resultado sem perder a precisão. Por exemplo:
2 + 3.1
(2).GetType().FullName
(2 + 3.1).GetType().FullName
5.1
System.Int32
System.Double
Se o resultado de uma operação for muito grande para o tipo, o tipo do resultado será ampliado para acomodar o resultado, como no exemplo a seguir:
(512MB).GetType().FullName
(512MB * 512MB).GetType().FullName
System.Int32
System.Double
O tipo do resultado nem sempre é o mesmo que um dos operandos. No exemplo a seguir, o valor negativo não pode ser convertido em um inteiro sem sinal e o inteiro sem sinal é muito grande para ser convertido Int32
em :
([int32]::minvalue + [uint32]::maxvalue).gettype().fullname
System.Int64
Neste exemplo, Int64
pode acomodar ambos os tipos.
O System.Decimal
tipo é uma exceção. Se um dos operandos tiver o tipo Decimal , o resultado será Tipo decimal . Qualquer resultado muito grande para o valor Decimal é um erro.
PS> [Decimal]::maxvalue
79228162514264337593543950335
PS> [Decimal]::maxvalue + 1
RuntimeException: Value was either too large or too small for a Decimal.
Potencial perda de precisão
Sempre que você tiver um resultado que exceda o intervalo do tipo, você corre o risco de perder a precisão devido à conversão de tipo. Por exemplo, adicionar um suficientemente grande [long]
e [int]
resulta na conversão dos operandos em [double]
. Neste exemplo, 9223372036854775807
é o valor máximo de um [long]
inteiro.
Adicionar ao valor excede o intervalo de [long]
.
PS> (9223372036854775807 + 2).GetType().FullName
System.Double
Converter o resultado em [ulong]
gera um resultado impreciso, porque os operandos foram coagidos a [double]
primeiro.
PS> [ulong](9223372036854775807 + 2)
9223372036854775808
Definir o valor maior como [ulong]
primeiro evita o problema e produz o resultado correto.
PS> 9223372036854775807ul + 2
9223372036854775809
No entanto, exceder o intervalo de [ulong]
resulta em um [double]
.
PS> ([ulong]::MaxValue + 1).GetType().FullName
System.Double
Aritmética bigint
Quando você executa operações aritméticas em [bigint]
números, o PowerShell usa converte todos os operandos [bigint]
em , o que resulta em truncamento de valores não inteiros. Por exemplo, o [double]
valor 1.9
é truncado para 1
quando convertido em [bigint]
.
PS> [bigint]1 / 1.9
1
PS> 1 / [bigint]1.9
1
Esse comportamento é diferente do comportamento de outros tipos numéricos. Neste exemplo, um [int]
dividido por um [double]
resulta em um [double]
. A conversão 1.9
em um [int]
arredonda o valor para cima até 2
.
PS> 1 / 1.9
0.526315789473684
PS> 1 / [int]1.9
0.5
Adicionando e multiplicando tipos não numéricos
Você pode adicionar números, cadeias de caracteres, matrizes e tabelas de hash. E você pode multiplicar números, cadeias de caracteres e matrizes. No entanto, você não pode multiplicar tabelas de hash.
Quando você adiciona cadeias de caracteres, matrizes ou tabelas de hash, os elementos são concatenados. Quando você concatena coleções, como matrizes ou tabelas de hash, um novo objeto é criado que contém os objetos de ambas as coleções. Se você tentar concatenar tabelas de hash que têm a mesma chave, a operação falhará.
Por exemplo, os seguintes comandos criam duas matrizes e as adicionam:
$a = 1,2,3
$b = "A","B","C"
$a + $b
1
2
3
A
B
C
Você também pode executar operações aritméticas em objetos de diferentes tipos. A operação que o PowerShell executa é determinada pelo tipo microsoft .NET do objeto mais à esquerda na operação. O PowerShell tenta converter todos os objetos na operação para o tipo .NET do primeiro objeto. Se ele conseguir converter os objetos, ele executará a operação apropriada para o tipo .NET do primeiro objeto. Se não conseguir converter nenhum dos objetos, a operação falhará.
Os exemplos a seguir demonstram o uso dos operadores de adição e multiplicação em operações que incluem tipos de objeto diferentes.
$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
Como o método usado para avaliar instruções é determinado pelo objeto mais à esquerda, a adição e a multiplicação no PowerShell não são estritamente comutativas. Por exemplo, (a + b)
nem sempre é igual (b + a)
a e (ab)
nem sempre é igual (ba)
a .
Os exemplos a seguir demonstram esse princípio:
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."
Tabelas de hash são um caso um pouco diferente. Você pode adicionar tabelas de hash a outra tabela de hash, desde que as tabelas de hash adicionadas não tenham chaves duplicadas.
O exemplo a seguir mostra como adicionar tabelas de hash umas às outras.
$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
O exemplo a seguir lança um erro porque uma das chaves é duplicada em ambas as tabelas de hash.
$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'
Além disso, você pode adicionar uma tabela de hash a uma matriz; e, toda a tabela de hash se torna um item na matriz.
$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
No entanto, você não pode adicionar nenhum outro tipo a uma tabela de hash.
$hash1 + 2
InvalidOperation: A hash table can only be added to another hash table.
Embora os operadores de adição sejam muito úteis, use os operadores de atribuição para adicionar elementos a tabelas e matrizes de hash. Para obter mais informações, consulte about_assignment_operators. Os exemplos a seguir usam o +=
operador de atribuição para adicionar itens a uma matriz:
$array = @()
(0..2).foreach{ $array += $_ }
$array
0
1
2
Operadores aritméticos e variáveis
Você também pode usar operadores aritméticos com variáveis. Os operadores atuam nos valores das variáveis. Os exemplos a seguir demonstram o uso de operadores aritméticos com variáveis:
PS> $intA = 6
PS> $intB = 4
PS> $intA + $intB
10
PS> $a = "Power"
PS> $b = "Shell"
PS> $a + $b
PowerShell
Comandos e operadores aritméticos
Normalmente, você usa os operadores aritméticos em expressões com números, cadeias de caracteres e matrizes. No entanto, você também pode usar operadores aritméticos com os objetos que os comandos retornam e com as propriedades desses objetos.
Os exemplos a seguir mostram como usar os operadores aritméticos em expressões com comandos do PowerShell:
(Get-Date) + (New-TimeSpan -day 1)
O operador parêntese força a avaliação do Get-Date
cmdlet e a avaliação da New-TimeSpan -Day 1
expressão de cmdlet, nessa ordem. Os dois resultados são adicionados usando o +
operador .
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
Na expressão acima, cada espaço de trabalho do processo ($_.ws
) é multiplicado por 2
; e, o resultado, comparado 50mb
com para ver se é maior que isso.
Operadores bit a bit
O PowerShell dá suporte aos operadores bit a bit padrão, incluindo and bit a bit (-band
), os operadores OR bit a bit inclusivos e exclusivos (-bor
e -bxor
) e bit a bit NOT (-bnot
).
A partir do PowerShell 2.0, todos os operadores bit a bit funcionam com inteiros de 64 bits.
A partir do PowerShell 3.0, os -shr
(shift-right) e -shl
(shift-left) são introduzidos para dar suporte à aritmética bit a bit no PowerShell.
O PowerShell dá suporte aos seguintes operadores bit a bit.
Operador | Descrição | Expression | Result |
---|---|---|---|
-band |
AND bit a bit | 10 -band 3 |
2 |
-bor |
OR bit a bit (inclusivo) | 10 -bor 3 |
11 |
-bxor |
OR bit a bit (exclusivo) | 10 -bxor 3 |
9 |
-bnot |
NOT bit a bit | -bNot 10 |
-11 |
-shl |
Shift-left | 102 -shl 2 |
408 |
-shr |
Shift-right | 102 -shr 1 |
51 |
Os operadores bit a bit atuam no formato binário de um valor. Por exemplo, a estrutura de bits para o número 10 é 00001010 (com base em 1 byte) e a estrutura de bits para o número 3 é 00000011. Quando você usa um operador bit a bit para comparar de 10 a 3, os bits individuais em cada byte são comparados.
Em uma operação AND bit a bit, o bit resultante é definido como 1 somente quando ambos os bits de entrada são 1.
1010 (10)
0011 ( 3)
-------------- bAND
0010 ( 2)
Em uma operação OR (inclusiva) bit a bit, o bit resultante é definido como 1 quando ou ambos os bits de entrada são 1. O bit resultante é definido como 0 somente quando ambos os bits de entrada são definidos como 0.
1010 (10)
0011 ( 3)
-------------- bOR (inclusive)
1011 (11)
Em uma operação OR (exclusiva) bit a bit, o bit resultante é definido como 1 somente quando um bit de entrada é 1.
1010 (10)
0011 ( 3)
-------------- bXOR (exclusive)
1001 ( 9)
O operador NOT bit a bit é um operador unário que produz o complemento binário do valor. Um bit de 1 é definido como 0 e um bit de 0 é definido como 1.
Por exemplo, o complemento binário de 0 é -1, o inteiro não assinado máximo (0xFFFFFFFF) e o complemento binário de -1 é 0.
-bNot 10
-11
0000 0000 0000 1010 (10)
------------------------- bNOT
1111 1111 1111 0101 (-11, 0xFFFFFFF5)
Em uma operação shift-left bit a bit, todos os bits são movidos "n" para a esquerda, onde "n" é o valor do operando à direita. Um zero é inserido no local.
Expressão | Result | Resultado binário |
---|---|---|
21 -shl 0 |
21 | 0001 0101 |
21 -shl 1 |
42 | 0010 1010 |
21 -shl 2 |
84 | 0101 0100 |
Em uma operação shift-right bit a bit, todos os bits são movidos "n" para a direita, em que "n" é especificado pelo operando à direita. O operador shift-right (-shr
) copia o bit de sinal para o lugar mais à esquerda ao deslocar um valor assinado. Para valores não assinados, um zero é inserido na posição mais à esquerda.
Expressão | Result | Binário | 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 |