Compartir a través de


about_Arithmetic_Operators

Descripción breve

Describe los operadores que realizan 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 para 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, se agregan ( -shr desplazamiento a la derecha) y -shl (desplazamiento a la izquierda) para admitir 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 de copia de cadenas y matrices por el número de veces especificado

    6 * 2       # result = 12
    @("!") * 4  # result = @("!","!","!","!")
    "!" * 3     # result = "!!!"
    
  • División (/): divide 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
    

Precedencia de operadores

PowerShell procesa operadores aritméticos en el orden siguiente:

Prioridad Operador 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 ha 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 $b[$a]de . La evaluación $a++ cambia el valor de después de $a que se use en la instrucción $c[$a++], pero antes de que se use en $b[$a]. La variable $a de $b[$a] es igual a 1, no 0. Por lo tanto, la instrucción asigna un valor a $b[1], no $b[0]a .

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 dar cabida a 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 primero [double] .

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, si se supera el intervalo de [ulong] resultados, se produce una [double]excepción .

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 en , lo que da como resultado el truncamiento de valores no enteros [bigint]. 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] elemento dividido por un [double] da como resultado un .[double] La conversión 1.9 a redondea [int] 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, los agregan:

$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 convierte correctamente los objetos, realiza la operación adecuada para el tipo de .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 las 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 a (ba).

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 se 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 hash y matrices. 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

Comandos y operadores 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 paréntesis fuerza la evaluación del Get-Date cmdlet y la evaluación de la expresión del New-TimeSpan -Day 1 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 and bit a bit (-band), los operadores OR inclusivos y exclusivos bit a bit (-bor y -bxor) y NOT bit a bit (-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 introducen los -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.

Operador 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 Mayús 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 es 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 de 10 a 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 (inclusiva) bit a bit, 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 (exclusiva) bit a bit, 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 a la izquierda bit a bit, todos los bits se mueven "n" a la izquierda, donde "n" es el valor del operando derecho. Se inserta un cero en el lugar.

Expresión 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 a la derecha bit a bit, todos los bits se mueven "n" a la derecha, donde el operando derecho especifica "n". El operador de desplazamiento a la derecha (-shr) copia el bit de signo en el lugar más a la izquierda al cambiar un valor con signo. En el caso de los valores sin signo, se inserta un cero en la posición más a la izquierda.

Expresión Resultado 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

Consulte también