Compartilhar via


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 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 (*) – Multiplique números ou copie cadeias de caracteres e matrizes o número de vezes especificado

    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
    
  • 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 Int32em :

([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

Confira também