about_Arithmetic_Operators

Breve descrição

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 para 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 strings, matrizes e hashtables. 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 trabalham em números de 64 bits.

A partir do PowerShell 3.0, o -shr (shift-right) e -shl (shift-left) são adicionados para dar suporte à aritmética bitwise no PowerShell. Os operadores bitwise só funcionam em tipos inteiros.

O PowerShell suporta os seguintes operadores aritméticos:

  • Adição (+) - Adiciona números, concatena cadeias de caracteres, matrizes e tabelas de hash

    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}
    
  • Subtração (-) - Subtrai ou nega números

    6 - 2   # result = 4
    - -6    # result = 6
    (Get-Date).AddDays(-1) # Yesterday's date
    
  • Multiplicação (*) - Multiplicar números ou copiar cadeias de caracteres e matrizes o número especificado de vezes

    6 * 2       # result = 12
    @("!") * 4  # result = @("!","!","!","!")
    "!" * 3     # result = "!!!"
    
  • Divisão (/) - Divide números

    6 / 2  # result = 3
    
  • Módulo (%) - retorna o restante de uma operação de divisão.

    7 % 2  # result = 1
    
  • Bitwise E (-band)

    5 -band 3  # result = 1
    
  • Bitwise NÃO (-bnot)

    -bnot 5  # result = -6
    
  • Bitwise OU (-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 dos operadores

O PowerShell processa operadores aritméticos na seguinte ordem:

Precedência Operator Description
5 () 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 diferir 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 de $b[$a]. A avaliação $a++ altera o valor de depois de ser usado na instrução $c[$a++], mas antes de $a ser usado em $b[$a]. A variável $a em $b[$a] igual , 1nã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 número inteiro par mais próximo.

O exemplo a seguir mostra o efeito do arredondamento para o número 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 .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 é ampliado para acomodar o resultado, como no exemplo a seguir:

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

O tipo de resultado nem sempre é o mesmo que um dos operandos. No exemplo a seguir, o valor negativo não pode ser convertido em um inteiro não assinado e o inteiro não assinado é muito grande para ser convertido em Int32:

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

Neste exemplo, Int64 pode acomodar ambos os tipos.

O System.Decimal tipo é uma exceção. Se qualquer operando 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.

Perda potencial 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. A adição de valor transborda o intervalo de [long].

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

Lançar o resultado para [ulong] produzir 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] resultados em um [double].

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

Aritmética de Bigint

Quando você executa operações aritméticas em [bigint] números, o PowerShell usa converte todos os operandos em , o [bigint]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]arquivo . A conversão 1.9 para um [int] arredonda o valor para 2.

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

Adicionando e multiplicando tipos não numéricos

Pode adicionar números, cadeias, matrizes e tabelas hash. E você pode multiplicar números, cadeias de caracteres e matrizes. No entanto, não é possível multiplicar tabelas de hash.

Ao adicionar cadeias, matrizes ou tabelas hash, os elementos são concatenados. Ao concatenar coleções, como matrizes ou tabelas hash, é criado um novo objeto que contém os objetos de ambas as coleções. Se tentar concatenar tabelas hash com a mesma chave, a operação falha.

Por exemplo, os comandos a seguir 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 executa a operação apropriada para o tipo .NET do primeiro objeto. Se ele não conseguir converter qualquer um 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 diferentes tipos de objeto.

$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)e (ab) nem sempre é igual (ba).

Os exemplos seguintes demonstram este 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."

As tabelas hash são um caso ligeiramente diferente. Pode adicionar tabelas hash a outra tabela hash, desde que as tabelas hash adicionadas não tenham chaves duplicadas.

O exemplo a seguir mostra como adicionar umas tabelas hash a 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 mostra um erro porque uma das chaves é duplicada em ambas as tabelas 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, pode adicionar uma tabela hash a uma matriz e toda a tabela hash irá tornar-se num 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, não é possível 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 sobre os 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

Operadores e comandos 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 comanda return 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 de parêntese força a avaliação do Get-Date cmdlet e a avaliação da New-TimeSpan -Day 1 expressão do cmdlet, nessa ordem. Ambos os resultados são entã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 para 50mb ver se é maior do que isso.

Operadores bit-a-bit

O PowerShell suporta os operadores bitwise padrão, incluindo bitwise-AND (-band), os operadores bitwise-OR inclusivos e exclusivos (-bor e -bxor) e bitwise-NOT (-bnot).

A partir do PowerShell 2.0, todos os operadores bit a bit trabalham com inteiros de 64 bits.

A partir do PowerShell 3.0, o -shr (shift-right) e -shl (shift-left) são introduzidos para dar suporte à aritmética bitwise no PowerShell.

O PowerShell oferece suporte aos seguintes operadores bitwise.

Operator Description Expression Result
-band Bitwise E 10 -band 3 2
-bor Bitwise OR (inclusive) 10 -bor 3 11
-bxor Bitwise OR (exclusivo) 10 -bxor 3 9
-bnot Bitwise NÃO -bNot 10 -11
-shl Deslocar-se para a esquerda 102 -shl 2 408
-shr Deslocar-se para a direita 102 -shr 1 51

Os operadores Bitwise 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 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 bit a bit OU (inclusive), o bit resultante é definido como 1 quando um 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 bit a bit OU (exclusiva), o bit resultante é definido como 1 somente quando um bit de entrada é 1.

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

O operador bit a bit NOT é um operador unário que produz o complemento binário do valor. Um pouco de 1 é definido como 0 e um pouco 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 bit a bit shift-left, todos os bits são movidos "n" lugares para a esquerda, onde "n" é o valor do operando direito. Um zero é inserido em um lugar.

Expression 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 bit a bit shift-right, todos os bits são movidos "n" lugares para a direita, onde "n" é especificado pelo operando direito. 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.

Expression 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

Consulte também