about_Arithmetic_Operators

簡短描述

描述在 PowerShell 中執行算術的運算子。

詳細描述

算術運算子會計算數值。 您可以使用一或多個算術運算符來加入、減去、乘法和除法值,以及計算除法運算的餘數(模數)。

加號 (+) 和乘法運算符 (*) 也會在字串、陣列和哈希表上運作。 加號運算符會串連輸入。 乘法運算符會傳回輸入的多個複本。 您甚至可以在算術語句中混合物件類型。 用來評估語句的方法是由表達式中最左邊物件的類型所決定。

從 PowerShell 2.0 開始,所有算術運算子都會在 64 位數位上運作。

從 PowerShell 3.0 開始, -shr 會新增 (shift-right) 和 -shl (shift-left) 以支援 PowerShell 中的位算術。 位運算子只適用於整數類型。

PowerShell 支援下列算術運算子:

  • 加法 (+) - 加入數位、串連字串、陣列和哈希表

    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}
    
  • 減法 (-) - 減去或否定數位

    6 - 2   # result = 4
    - -6    # result = 6
    (Get-Date).AddDays(-1) # Yesterday's date
    
  • 乘法 (*) - 乘數或複製字串,並陣列指定的次數

    6 * 2       # result = 12
    @("!") * 4  # result = @("!","!","!","!")
    "!" * 3     # result = "!!!"
    
  • 除法 (/) - 除數

    6 / 2  # result = 3
    
  • 模數 (%) - 傳回除法運算的其餘部分。

    7 % 2  # result = 1
    
  • 位 AND (-band

    5 -band 3  # result = 1
    
  • 位 NOT (-bnot

    -bnot 5  # result = -6
    
  • 位 OR (-bor

    5 -bor 0x03  # result = 7
    
  • 位 XOR (-bxor

    5 -bxor 3   # result = 6
    
  • 移位 (-shl

    102 -shl 2  # result = 408
    
  • 移至右移位 (-shr

    102 -shr 2  # result = 25
    

運算子優先順序

PowerShell 會依下列順序處理算術運算符:

優先順序 運算子 描述
1 () 括號
2 - 若為負數或一元運算符
3 *、 、 /% 用於乘法和除法
4 +, - 用於加法和減法
5 -band, -bnot 針對位作業
5 -bor, -bxor 針對位作業
5 -shr, -shl 針對位作業

PowerShell 會根據優先順序規則,從左至右處理表達式。 下列範例顯示優先順序規則的效果:

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

PowerShell 評估表達式的順序可能與您使用的其他程式設計和腳本語言不同。 下列範例顯示複雜的指派語句。

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

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

在此範例中,表達式 $a++ 會在 之前 $b[$a]進行評估。 評估 $a++ 會變更 在語句$c[$a++]中使用 之後的值$a,但在 中使用 $b[$a]之前。 中的 $b[$a] 變數$a等於1,而不是 0。 因此,語句會將值指派給 $b[1],而不是 $b[0]

上述程式代碼相當於:

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

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

除法和四捨五入

當除法運算的商數是整數時,PowerShell 會將值四捨五入為最接近的整數。 當值為 .5時,它會四捨五入為最接近的偶數整數。

下列範例顯示四捨五入至最接近偶數整數的效果。

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

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

您可以使用 類別 [Math] 來取得不同的四捨五入行為。

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

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

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

如需詳細資訊,請參閱 Math.Round 方法。

要容納結果的類型轉換

PowerShell 會自動選取最能表示結果的 .NET 數值類型,而不會失去精確度。 例如:

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

如果作業的結果對型別而言太大,結果的類型就會擴大以容納結果,如下列範例所示:

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

結果的類型不一定與其中一個操作數相同。 在下列範例中,負值無法轉換成不帶正負號的整數,而且不帶正負號的整數太大而無法轉換成 Int32

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

在此範例中, Int64 可以容納這兩種類型。

System.Decimal 類型為例外狀況。 如果任一操作數具有 Decimal 類型,則結果為 Decimal 類型。 小數點值的任何結果太大都是錯誤。

PS> [Decimal]::maxvalue
79228162514264337593543950335

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

可能遺失有效位數

每當您有超過類型範圍的結果時,您都可能會因為類型轉換而失去精確度。 例如,新增夠大的 [long] ,並 [int] 導致操作數轉換成 [double]。 在此範例中, 9223372036854775807 是整數的 [long] 最大值。 加入至 值會溢位 的範圍 [long]

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

將結果 [ulong] 轉換成產生不正確的結果,因為操作數會強制為 [double] 第一個結果。

PS> [ulong](9223372036854775807 + 2)
9223372036854775808

先定義較大的值 [ulong] 會避免問題,併產生正確的結果。

PS> 9223372036854775807ul + 2
9223372036854775809

不過,超過 中[double]的結果範圍[ulong]

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

Bigint 算術

當您對 [bigint] 數位執行算術運算時,PowerShell 會使用 將所有操作數 [bigint]轉換成 ,這會導致截斷非整數值。 例如,當轉換成 時, [double]1.9 會截斷 1[bigint]

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

此行為與其他數值類型的行為不同。 在這裡範例中, [int] 除以 [double] 的結果為 [double][int]轉換成 1.9 會將值四捨五入為 2

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

加入和乘以非數值類型

您可以新增數位、字串、數位和哈希表。 而且,您可以將數位、字串和數位相乘。 不過,您無法將哈希表相乘。

當您新增字串、陣列或哈希表時,元素會串連。 當您串連集合,例如數位或哈希表時,會建立新的物件,其中包含這兩個集合中的物件。 如果您嘗試串連具有相同索引鍵的哈希表,作業會失敗。

例如,下列命令會建立兩個陣列,然後加以新增:

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

您也可以對不同類型的物件執行算術運算。 PowerShell 執行的作業是由作業中最左邊物件的 Microsoft .NET 類型所決定。 PowerShell 會嘗試將作業中的所有物件轉換成第一個物件的 .NET 類型。 如果成功轉換物件,它會執行第一個物件的 .NET 類型適用的作業。 如果無法轉換任何物件,作業就會失敗。

下列範例示範如何在包含不同物件類型的作業中使用加法和乘法運算符。

$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

因為用來評估語句的方法是由最左邊的對象所決定,因此PowerShell中的加法和乘法並非絕對通勤。 例如, (a + b) 不一定等於 (b + a),而且 (ab) 不一定等於 (ba)

下列範例示範此原則:

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

哈希表的情況稍有不同。 您可以將哈希表新增至另一個哈希表,只要新增的哈希表沒有重複的索引鍵。

下列範例示範如何將哈希表新增至彼此。

$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

下列範例會擲回錯誤,因為這兩個哈希表中的其中一個索引鍵重複。

$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'

此外,您可以將哈希表新增至陣列;和,整個哈希表會成為陣列中的專案。

$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

不過,您無法將任何其他類型新增至哈希表。

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

雖然加法運算子非常有用,但請使用指派運算符將元素加入哈希表和數位。 如需詳細資訊,請參閱 about_assignment_operators。 下列範例會 += 使用指派運算符將專案新增至數位:

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

算術運算子和變數

您也可以搭配變數使用算術運算元。 運算子會根據變數的值採取行動。 下列範例示範搭配變數使用算術運算子:

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

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

算術運算子和命令

一般而言,您會在表達式中使用算術運算元搭配數位、字串和陣列。 不過,您也可以使用算術運算元搭配命令傳回的物件,以及這些對象的屬性。

下列範例示範如何在表達式中使用算術運算符搭配 PowerShell 命令:

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

括號運算子會依該順序強制評估 Get-Date Cmdlet 和 Cmdlet 表達式的 New-TimeSpan -Day 1 評估。 接著會使用 + 運算符來新增這兩個結果。

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

在上述表達式中,每個進程工作空間 ($_.ws) 都會乘 2以 ;而結果會與 比較 50mb ,以查看其是否大於。

位元運算子

PowerShell 支援標準位運算元,包括 bitwise-AND (-band)、包含和獨佔位 OR 運算符 (-bor-bxor),以及 bitwise-NOT (-bnot)。

從 PowerShell 2.0 開始,所有位運算符都會使用 64 位整數。

從 PowerShell 3.0 開始, -shr 會引進 (shift-right) 和 -shl (shift-left) 以支援 PowerShell 中的位算術。

PowerShell 支援下列位運算符。

運算子 描述 運算是 結果
-band 位元 AND 10 -band 3 2
-bor 位 OR (含) 10 -bor 3 11
-bxor 位 OR (獨佔) 10 -bxor 3 9
-bnot 位元 NOT -bNot 10 -11
-shl 左移 102 -shl 2 408
-shr 右移 102 -shr 1 51

位運算子會根據值的二進位格式採取行動。 例如,數位 10 的位結構是00001010(以 1 位元組為基礎),而數位 3 的位結構00000011。 當您使用位運算符比較 10 到 3 時,會比較每個位元組中的個別位。

在位 AND 運算中,只有在兩個輸入位都是 1 時,產生的位才會設定為 1。

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

在位 OR (含) 作業中,當或兩個輸入位都為 1 時,產生的位會設定為 1。 只有當兩個輸入位都設定為 0 時,產生的位才會設定為 0。

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

在位 OR (獨佔) 作業中,產生的位只有在一個輸入位的 1 時,才會設定為 1。

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

位 NOT 運算子是一元運算子,會產生值的二進位補碼。 1 位設定為 0,而 0 位設定為 1。

例如,0 的二進位補碼為 -1、最大無符號整數 (0xFFFFFFFF),而 -1 的二進位補碼為 0。

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

在位移左運算中,所有位都會移至左邊的 「n」 位置,其中 「n」 是右操作數的值。 零會插入其中一個位置。

運算式 結果 二進位結果
21 -shl 0 21 0001 0101
21 -shl 1 42 0010 1010
21 -shl 2 84 0101 0100

在位移右運算中,所有位都會移至右邊的 「n」 位置,其中 「n」 是由右操作數指定。 shift-right 運算子 (-shr) 會在移動帶正負號值時,將符號位複製到最左邊的位置。 對於不帶正負號的值,零會插入最左邊的位置。

運算式 結果 二進位 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

另請參閱