about_Arithmetic_Operators

Descripción breve

Describe los operadores que realizan la aritmética en PowerShell.

Descripción larga

Los operadores aritméticos calculan valores numéricos. Puede usar uno o varios operadores aritméticos para agregar, restar, multiplicar y dividir valores y calcular el resto (módulo) de una operación de división.

El operador de suma (+) y el operador de multiplicación (*) también funcionan en cadenas, matrices y tablas hash. El operador de suma concatena la entrada. El operador de multiplicación devuelve varias copias de la entrada. Incluso puede mezclar tipos de objeto en una instrucción aritmética. El método que se usa para evaluar la instrucción viene determinado por el tipo del objeto situado más a la izquierda en la expresión.

A partir de PowerShell 2.0, todos los operadores aritméticos funcionan en números de 64 bits.

A partir de PowerShell 3.0, -shr se agregan (desplazamiento a la derecha) y -shl (desplazamiento a la izquierda) para admitir la aritmética bit a bit en PowerShell. Los operadores bit a bit solo funcionan en tipos enteros.

PowerShell admite los siguientes operadores aritméticos:

  • Suma (+): agrega números, concatena cadenas, matrices y tablas 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}
    
  • Resta (-): resta o niega números

    6 - 2   # result = 4
    - -6    # result = 6
    (Get-Date).AddDays(-1) # Yesterday's date
    
  • Multiplicación (*): multiplicación de números o cadenas de copia y matrices el número de veces especificado

    6 * 2       # result = 12
    @("!") * 4  # result = @("!","!","!","!")
    "!" * 3     # result = "!!!"
    
  • División (/): divide los números

    6 / 2  # result = 3
    
  • Módulo (%): devuelve el resto de una operación de división.

    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
    
  • Desplaza bits a la izquierda (-shl)

    102 -shl 2  # result = 408
    
  • Desplaza bits a la derecha (-shr)

    102 -shr 2  # result = 25
    

Prioridad de los operadores

PowerShell procesa operadores aritméticos en el orden siguiente:

Prioridad Operator Descripción
1 () Paréntesis
2 - Para un número negativo o un operador unario
3 *, , /, % Para multiplicación y división
4 +, - Para suma y resta
5 -band, -bnot Para las operaciones bit a bit
5 -bor, -bxor Para las operaciones bit a bit
5 -shr, -shl Para las operaciones bit a bit

PowerShell procesa las expresiones de izquierda a derecha según las reglas de precedencia. En los ejemplos siguientes se muestra el efecto de las reglas de precedencia:

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

El orden en que PowerShell evalúa las expresiones puede diferir de otros lenguajes de programación y scripting que haya usado. En el ejemplo siguiente se muestra una instrucción de asignación complicada.

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

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

En este ejemplo, la expresión $a++ se evalúa antes de $b[$a]. Evaluar $a++ cambia el valor de después de $a usarlo en la instrucción $c[$a++], pero antes de usarlo en $b[$a]. La variable $a de $b[$a] es igual 1a , no 0. Por lo tanto, la instrucción asigna un valor a $b[1], no $b[0].

El código anterior es equivalente a:

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

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

División y redondeo

Cuando el cociente de una operación de división es un entero, PowerShell redondea el valor al entero más cercano. Cuando el valor es .5, se redondea al entero par más cercano.

En el ejemplo siguiente se muestra el efecto de redondear al entero par más cercano.

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

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

Puede usar la [Math] clase para obtener un comportamiento de redondeo 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 obtener más información, consulte el método Math.Round .

Conversión de tipos para dar cabida al resultado

PowerShell selecciona automáticamente el tipo numérico de .NET que mejor expresa el resultado sin perder precisión. Por ejemplo:

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

Si el resultado de una operación es demasiado grande para el tipo, el tipo del resultado se amplía para dar cabida al resultado, como en el ejemplo siguiente:

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

El tipo del resultado no siempre es el mismo que uno de los operandos. En el ejemplo siguiente, el valor negativo no se puede convertir en un entero sin signo y el entero sin signo es demasiado grande para convertirse en Int32:

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

En este ejemplo, Int64 puede acomodar ambos tipos.

El System.Decimal tipo es una excepción. Si alguno de los operandos tiene el tipo Decimal , el resultado es Tipo decimal . Cualquier resultado demasiado grande para el valor decimal es un error.

PS> [Decimal]::maxvalue
79228162514264337593543950335

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

Posible pérdida de precisión

Cada vez que tenga un resultado que supere el intervalo del tipo, corre el riesgo de perder precisión debido a la conversión de tipos. Por ejemplo, agregar un valor suficientemente grande [long] y [int] da como resultado que los operandos se conviertan en [double]. En este ejemplo, 9223372036854775807 es el valor máximo de un [long] entero. Al agregar al valor se desborda el intervalo de [long].

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

Convertir el resultado en [ulong] produce un resultado inexacto, ya que los operandos se coercieron a [double] primero.

PS> [ulong](9223372036854775807 + 2)
9223372036854775808

Definir el valor mayor como [ulong] primero evita el problema y genera el resultado correcto.

PS> 9223372036854775807ul + 2
9223372036854775809

Sin embargo, superar el intervalo de [ulong] resultados en un [double].

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

Aritmética bigint

Al realizar operaciones aritméticas en [bigint] números, PowerShell usa convierte todos los operandos [bigint]en , lo que da como resultado el truncamiento de valores no enteros. Por ejemplo, el [double] valor 1.9 se trunca a 1 cuando se convierte en [bigint].

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

Este comportamiento es diferente del comportamiento de otros tipos numéricos. En este ejemplo, un [int] objeto dividido por un [double] da como resultado un [double]. La conversión 1.9 a un [int] redondea el valor hasta 2.

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

Adición y multiplicación de tipos no numéricos

Puede agregar números, cadenas, matrices y tablas hash. Además, puede multiplicar números, cadenas y matrices. Sin embargo, no se pueden multiplicar las tablas hash.

Al agregar cadenas, matrices o tablas hash, los elementos se concatenan. Al concatenar colecciones, como matrices o tablas hash, se crea un nuevo objeto que contiene los objetos de ambas colecciones. Si intenta concatenar tablas hash que tienen la misma clave, se produce un error en la operación.

Por ejemplo, los siguientes comandos crean dos matrices y, a continuación, agréguelas:

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

También puede realizar operaciones aritméticas en objetos de diferentes tipos. La operación que realiza PowerShell viene determinada por el tipo de Microsoft .NET del objeto situado más a la izquierda en la operación. PowerShell intenta convertir todos los objetos de la operación en el tipo .NET del primer objeto. Si se realiza correctamente la conversión de los objetos, realiza la operación adecuada para el tipo .NET del primer objeto. Si no se puede convertir cualquiera de los objetos, se produce un error en la operación.

En los ejemplos siguientes se muestra el uso de los operadores de suma y multiplicación en operaciones que incluyen diferentes tipos de objetos.

$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

Dado que el método que se usa para evaluar instrucciones viene determinado por el objeto situado más a la izquierda, la suma y la multiplicación en PowerShell no son estrictamente conmutantes. Por ejemplo, (a + b) no siempre es igual (b + a)a y (ab) no siempre es igual (ba)a .

En los ejemplos siguientes se muestra este principio:

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."

Las tablas hash son un caso ligeramente diferente. Puede agregar tablas hash a otra tabla hash, siempre y cuando las tablas hash agregadas no tengan claves duplicadas.

En el ejemplo siguiente se muestra cómo agregar tablas hash entre sí.

$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

En el ejemplo siguiente se produce un error porque una de las claves está duplicada en ambas tablas 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'

Además, puede agregar una tabla hash a una matriz; y, toda la tabla hash se convierte en un elemento de la 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

Sin embargo, no puede agregar ningún otro tipo a una tabla hash.

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

Aunque los operadores de suma son muy útiles, use los operadores de asignación para agregar elementos a tablas y matrices hash. Para obtener más información, consulte about_assignment_operators. En los ejemplos siguientes se usa el += operador de asignación para agregar elementos a una matriz:

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

Operadores aritméticos y variables

También puede usar operadores aritméticos con variables. Los operadores actúan sobre los valores de las variables. En los ejemplos siguientes se muestra el uso de operadores aritméticos con variables:

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

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

Operadores y comandos aritméticos

Normalmente, se usan los operadores aritméticos en expresiones con números, cadenas y matrices. Sin embargo, también puede usar operadores aritméticos con los objetos que los comandos devuelven y con las propiedades de esos objetos.

En los ejemplos siguientes se muestra cómo usar los operadores aritméticos en expresiones con comandos de PowerShell:

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

El operador de paréntesis fuerza la evaluación del Get-Date cmdlet y la evaluación de la New-TimeSpan -Day 1 expresión de cmdlet, en ese orden. A continuación, se agregan ambos resultados mediante el + 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

En la expresión anterior, cada espacio de trabajo de proceso ($_.ws) se multiplica por 2; y, el resultado, comparado con 50mb para ver si es mayor que eso.

Operadores bit a bit

PowerShell admite los operadores bit a bit estándar, incluidos bit a bit-AND (-band), los operadores inclusivos y exclusivos bit a bit-OR (-bor y -bxor) y bit a bit-NOT (-bnot).

A partir de PowerShell 2.0, todos los operadores bit a bit funcionan con enteros de 64 bits.

A partir de PowerShell 3.0, se presentan ( -shr desplazamiento a la derecha) y -shl (desplazamiento a la izquierda) para admitir la aritmética bit a bit en PowerShell.

PowerShell admite los siguientes operadores bit a bit.

Operator Descripción Expression Resultado
-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 Desplazamiento a la izquierda 102 -shl 2 408
-shr Desplazamiento a la derecha 102 -shr 1 51

Los operadores bit a bit actúan en el formato binario de un valor. Por ejemplo, la estructura de bits del número 10 se 00001010 (basada en 1 byte) y la estructura de bits del número 3 es 00000011. Cuando se usa un operador bit a bit para comparar entre 10 y 3, se comparan los bits individuales de cada byte.

En una operación AND bit a bit, el bit resultante se establece en 1 solo cuando ambos bits de entrada son 1.

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

En una operación OR bit a bit (inclusiva), el bit resultante se establece en 1 cuando o ambos bits de entrada son 1. El bit resultante se establece en 0 solo cuando ambos bits de entrada se establecen en 0.

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

En una operación OR bit a bit (exclusiva), el bit resultante se establece en 1 solo cuando un bit de entrada es 1.

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

El operador NOT bit a bit es un operador unario que genera el complemento binario del valor. Un bit de 1 se establece en 0 y un bit de 0 se establece en 1.

Por ejemplo, el complemento binario de 0 es -1, el entero sin signo máximo (0xFFFFFFFF) y el complemento binario de -1 es 0.

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

En una operación de desplazamiento bit a bit a la izquierda, todos los bits se mueven "n" a la izquierda, donde "n" es el valor del operando derecho. Se inserta un cero en el lugar.

Expression Resultado Resultado binario
21 -shl 0 21 0001 0101
21 -shl 1 42 0010 1010
21 -shl 2 84 0101 0100

En una operación de desplazamiento bit a bit a la derecha, todos los bits se mueven "n" a la derecha, donde el operando derecho especifica "n". El operador shift-right (-shr) copia el bit de signo en el lugar más a la izquierda al cambiar un valor con signo. Para los valores sin firmar, se inserta un cero en la posición más izquierda.

Expression Resultado Binario 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 también