about_Arithmetic_Operators

Descrizione breve

Descrive gli operatori che eseguono operazioni aritmetiche in PowerShell.

Descrizione lunga

Gli operatori aritmetici calcolano i valori numerici. È possibile usare uno o più operatori aritmetici per aggiungere, sottrarre, moltiplicare e dividere i valori e calcolare il resto (modulo) di un'operazione di divisione.

L'operatore di addizione (+) e l'operatore di moltiplicazione (*) operano anche su stringhe, matrici e tabelle hash. L'operatore di addizione concatena l'input. L'operatore di moltiplicazione restituisce più copie dell'input. È anche possibile combinare tipi di oggetto in un'istruzione aritmetica. Il metodo utilizzato per valutare l'istruzione è determinato dal tipo dell'oggetto più a sinistra nell'espressione.

A partire da PowerShell 2.0, tutti gli operatori aritmetici funzionano su numeri a 64 bit.

A partire da PowerShell 3.0, ( -shr maiusc-destra) e -shl (maiusc-sinistra) vengono aggiunti per supportare l'aritmetica bit per bit in PowerShell. Gli operatori bit per bit funzionano solo sui tipi integer.

PowerShell supporta gli operatori aritmetici seguenti:

  • Addizione (+) - Aggiunge numeri, concatena stringhe, matrici e tabelle 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}
    
  • Sottrazione (-) - Sottrae o nega numeri

    6 - 2   # result = 4
    - -6    # result = 6
    (Get-Date).AddDays(-1) # Yesterday's date
    
  • Moltiplicazione (*): moltiplicare numeri o copiare stringhe e matrici il numero di volte specificato

    6 * 2       # result = 12
    @("!") * 4  # result = @("!","!","!","!")
    "!" * 3     # result = "!!!"
    
  • Divisione (/) - Divide i numeri

    6 / 2  # result = 3
    
  • Modulo (%): restituisce il resto di un'operazione di divisione.

    7 % 2  # result = 1
    
  • AND bit per bit (-band)

    5 -band 3  # result = 1
    
  • NOT bit per bit (-bnot)

    -bnot 5  # result = -6
    
  • OR bit per bit (-bor)

    5 -bor 0x03  # result = 7
    
  • XOR bit per bit (-bxor)

    5 -bxor 3   # result = 6
    
  • Sposta i bit a sinistra (-shl)

    102 -shl 2  # result = 408
    
  • Sposta i bit a destra (-shr)

    102 -shr 2  # result = 25
    

Precedenza tra gli operatori

PowerShell elabora gli operatori aritmetici nell'ordine seguente:

Precedenza Operatore Descrizione
1 () Parentesi
2 - Per un numero negativo o un operatore unario
3 *, /, % Per moltiplicazione e divisione
4 +, - Per addizione e sottrazione
5 -band, -bnot Per operazioni bit per bit
5 -bor, -bxor Per operazioni bit per bit
5 -shr, -shl Per operazioni bit per bit

PowerShell elabora le espressioni da sinistra a destra in base alle regole di precedenza. Gli esempi seguenti illustrano l'effetto delle regole di precedenza:

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

L'ordine in cui PowerShell valuta le espressioni può differire da altri linguaggi di programmazione e scripting usati. L'esempio seguente mostra un'istruzione di assegnazione complessa.

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

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

In questo esempio l'espressione $a++ viene valutata prima di $b[$a]. $a++ La valutazione modifica il valore di $a dopo che viene usata nell'istruzione $c[$a++], ma prima che venga usata in $b[$a]. La variabile $a in è uguale 1a , non 0$b[$a] . Pertanto, l'istruzione assegna un valore a , non $b[0]a $b[1].

Il codice precedente equivale a:

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

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

Divisione e arrotondamento

Quando il quoziente di un'operazione di divisione è un numero intero, PowerShell arrotonda il valore all'intero più vicino. Quando il valore è .5, arrotonda all'intero pari più vicino.

Nell'esempio seguente viene illustrato l'effetto dell'arrotondamento al numero intero pari più vicino.

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

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

È possibile usare la [Math] classe per ottenere un comportamento di arrotondamento diverso.

PS> [int][Math]::Round(5 / 2,[MidpointRounding]::AwayFromZero)
3

PS> [int][Math]::Ceiling(5 / 2)
3

PS> [int][Math]::Floor(5 / 2)
2

Per altre informazioni, vedere il metodo Math.Round .

Conversione dei tipi in base al risultato

PowerShell seleziona automaticamente il tipo numerico .NET che esprime meglio il risultato senza perdere precisione. Ad esempio:

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

Se il risultato di un'operazione è troppo grande per il tipo, il tipo del risultato viene ampliato per contenere il risultato, come nell'esempio seguente:

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

Il tipo del risultato non è sempre uguale a uno degli operandi. Nell'esempio seguente il valore negativo non può essere sottoposto a cast a un intero senza segno e l'intero senza segno è troppo grande per essere sottoposto a cast in Int32:

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

In questo esempio, Int64 può contenere entrambi i tipi.

Il System.Decimal tipo è un'eccezione. Se uno degli operandi ha il tipo Decimal , il risultato è decimale . Qualsiasi risultato troppo grande per il valore Decimal è un errore.

PS> [Decimal]::maxvalue
79228162514264337593543950335

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

Potenziale perdita di precisione

Ogni volta che si ha un risultato che supera l'intervallo del tipo, si rischia di perdere precisione a causa della conversione del tipo. Ad esempio, l'aggiunta di un oggetto sufficientemente grande [long] e [int] comporta la conversione degli operandi in [double]. In questo esempio è 9223372036854775807 il valore massimo di un [long] numero intero. L'aggiunta al valore supera l'intervallo di [long].

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

Eseguire il cast del risultato per [ulong] produrre un risultato impreciso, perché gli operandi sono stati costretti per primi.[double]

PS> [ulong](9223372036854775807 + 2)
9223372036854775808

La definizione del valore più grande come [ulong] prima evita il problema e produce il risultato corretto.

PS> 9223372036854775807ul + 2
9223372036854775809

Tuttavia, superando l'intervallo di [ulong] risultati in un oggetto [double].

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

Aritmetica bigint

Quando si eseguono operazioni aritmetiche sui [bigint] numeri, PowerShell usa converte tutti gli operandi in [bigint], che comporta il troncamento di valori non integer. Ad esempio, il [double] valore 1.9 viene troncato in 1 quando viene convertito in [bigint].

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

Questo comportamento è diverso dal comportamento di altri tipi numerici. In questo esempio, un oggetto [int] diviso per un [double] risultato in un oggetto [double]. Il cast 1.9 a un [int] oggetto arrotonda il valore fino a 2.

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

Aggiunta e moltiplicazione di tipi non numerici

È possibile aggiungere numeri, stringhe, matrici e tabelle hash. È anche possibile moltiplicare numeri, stringhe e matrici. Tuttavia, non è possibile moltiplicare le tabelle hash.

Quando si aggiungono stringhe, matrici o tabelle hash, gli elementi vengono concatenati. Quando si concatenano raccolte, ad esempio matrici o tabelle hash, viene creato un nuovo oggetto contenente gli oggetti di entrambe le raccolte. Se si tenta di concatenare tabelle hash con la stessa chiave, l'operazione ha esito negativo.

Ad esempio, i comandi seguenti creano due matrici e quindi le aggiungono:

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

È anche possibile eseguire operazioni aritmetiche su oggetti di tipi diversi. L'operazione eseguita da PowerShell è determinata dal tipo Microsoft .NET dell'oggetto più a sinistra nell'operazione. PowerShell tenta di convertire tutti gli oggetti nell'operazione nel tipo .NET del primo oggetto. Se riesce a convertire gli oggetti, esegue l'operazione appropriata per il tipo .NET del primo oggetto. Se non riesce a convertire uno degli oggetti, l'operazione non riesce.

Negli esempi seguenti viene illustrato l'uso degli operatori di addizione e moltiplicazione nelle operazioni che includono tipi di oggetto diversi.

$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

Poiché il metodo usato per valutare le istruzioni è determinato dall'oggetto più a sinistra, l'aggiunta e la moltiplicazione in PowerShell non sono strettamente commutative. Ad esempio, (a + b) non sempre uguale (b + a)a e (ab) non sempre uguale (ba)a .

Gli esempi seguenti illustrano questo 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."

Le tabelle hash sono un caso leggermente diverso. È possibile aggiungere tabelle hash a un'altra tabella hash, purché le tabelle hash aggiunte non abbiano chiavi duplicate.

Nell'esempio seguente viene illustrato come aggiungere tabelle hash l'una all'altra.

$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

Nell'esempio seguente viene generato un errore perché una delle chiavi è duplicata in entrambe le tabelle 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'

Inoltre, è possibile aggiungere una tabella hash a una matrice; e, l'intera tabella hash diventa un elemento nella matrice.

$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

Tuttavia, non è possibile aggiungere altri tipi a una tabella hash.

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

Anche se gli operatori di addizione sono molto utili, usare gli operatori di assegnazione per aggiungere elementi a tabelle hash e matrici. Per altre informazioni, vedere about_assignment_operators. Gli esempi seguenti usano l'operatore += di assegnazione per aggiungere elementi a una matrice:

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

Operatori e variabili aritmetici

È anche possibile usare operatori aritmetici con variabili. Gli operatori agiscono sui valori delle variabili. Gli esempi seguenti illustrano l'uso di operatori aritmetici con variabili:

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

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

Operatori e comandi aritmetici

In genere, si usano gli operatori aritmetici nelle espressioni con numeri, stringhe e matrici. Tuttavia, è anche possibile usare operatori aritmetici con gli oggetti restituiti dai comandi e con le proprietà di tali oggetti.

Gli esempi seguenti illustrano come usare gli operatori aritmetici nelle espressioni con i comandi di PowerShell:

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

L'operatore parentesi forza la valutazione del Get-Date cmdlet e la valutazione dell'espressione New-TimeSpan -Day 1 cmdlet, in tale ordine. Entrambi i risultati vengono quindi aggiunti usando l'operatore + .

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

Nell'espressione precedente, ogni spazio di lavoro del processo ($_.ws) viene moltiplicato per 2; e, il risultato, rispetto 50mb a per verificare se è maggiore di quello.

Operatori bit per bit

PowerShell supporta gli operatori bit per bit standard, incluso AND bit per bit (-band), gli operatori OR bit per bit inclusivi ed esclusivi bit per bit (-bor e -bxor) e NOT bit per bit (-bnot).

A partire da PowerShell 2.0, tutti gli operatori bit per bit funzionano con interi a 64 bit.

A partire da PowerShell 3.0, vengono -shr introdotti (shift-right) e -shl (shift-left) per supportare l'aritmetica bit per bit in PowerShell.

PowerShell supporta gli operatori bit per bit seguenti.

Operatore Descrizione Espressione Risultato
-band AND bit per bit 10 -band 3 2
-bor OR bit per bit (inclusivo) 10 -bor 3 11
-bxor OR bit per bit (esclusivo) 10 -bxor 3 9
-bnot NOT bit per bit -bNot 10 -11
-shl Test di spostamento 102 -shl 2 408
-shr Test di spostamento 102 -shr 1 51

Gli operatori bit per bit agiscono sul formato binario di un valore. Ad esempio, la struttura di bit per il numero 10 è 00001010 (in base a 1 byte) e la struttura di bit per il numero 3 è 00000011. Quando si usa un operatore bit per bit per confrontare 10 a 3, vengono confrontati i singoli bit in ogni byte.

In un'operazione AND bit per bit, il bit risultante è impostato su 1 solo quando entrambi i bit di input sono 1.

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

In un'operazione OR bit per bit (inclusivo), il bit risultante è impostato su 1 quando o entrambi i bit di input sono 1. Il bit risultante è impostato su 0 solo quando entrambi i bit di input sono impostati su 0.

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

In un'operazione OR bit per bit (esclusiva), il bit risultante è impostato su 1 solo quando un bit di input è 1.

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

L'operatore NOT bit per bit è un operatore unario che produce il complemento binario del valore. Un bit di 1 è impostato su 0 e un bit di 0 è impostato su 1.

Ad esempio, il complemento binario di 0 è -1, l'intero senza segno massimo (0xFFFFFFFF) e il complemento binario di -1 è 0.

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

In un'operazione di spostamento bit per bit a sinistra, tutti i bit vengono spostati "n" a sinistra, dove "n" è il valore dell'operando destro. Uno zero viene inserito in quelle posizioni.

Espressione Risultato Risultato binario
21 -shl 0 21 0001 0101
21 -shl 1 42 0010 1010
21 -shl 2 84 0101 0100

In un'operazione di spostamento bit per bit a destra, tutti i bit vengono spostati "n" a destra, dove "n" viene specificato dall'operando destro. L'operatore shift-right (-shr) copia il bit del segno nella posizione più a sinistra quando si sposta un valore con segno. Per i valori senza segno, viene inserito uno zero nella posizione più a sinistra.

Espressione Risultato 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

Vedi anche