about_Arithmetic_Operators
简短说明
介绍在 PowerShell 中执行算术的运算符。
长说明
算术运算符计算数值。 可以使用一个或多个算术运算符来添加、减去、乘法和除法值,并计算除法运算) 的余数 (模数。
加法运算符 (+
) 和乘法运算符 (*
) 也对字符串、数组和哈希表进行操作。 加法运算符连接输入。
乘法运算符返回输入的多个副本。 甚至可以在算术语句中混合对象类型。 用于计算 语句的方法由表达式中最左侧对象的类型确定。
从 PowerShell 2.0 开始,所有算术运算符都处理 64 位数字。
从 PowerShell 3.0 开始, -shr
将添加 (向右移) 和 -shl
(左移) ,以支持 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
按位“与”(
-band
)5 -band 3 # result = 1
按位不 (
-bnot
)-bnot 5 # result = -6
按位或 (
-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++]
中使用后,但在 中$b[$a]
使用它之前,求值会更改 $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 方法。
添加和乘法非数值类型
可以添加数字、字符串、数组和哈希表。 还可以将数字、字符串和数组相乘。 但是,不能将哈希表相乘。
添加字符串、数组或哈希表时,元素会连接在一起。 连接集合(如数组或哈希表)时,将创建一个新对象,其中包含这两个集合中的 对象。 如果尝试连接具有相同键的哈希表,操作将失败。
例如,以下命令创建两个数组,然后添加它们:
$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..9).foreach{ $array += $_ }
$array
0
1
2
类型转换以适应结果
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 类型。 对于 Decimal 值而言,任何太大的结果都是错误。
PS> [Decimal]::maxvalue
79228162514264337593543950335
PS> [Decimal]::maxvalue + 1
RuntimeException: Value was either too large or too small for a Decimal.
算术运算符和变量
还可以将算术运算符与变量配合使用。 运算符作用于变量的值。 以下示例演示如何将算术运算符与变量配合使用:
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 支持标准位运算符,包括按位和 (-band
) 、非独占位或 (-bor
和 -bxor
) 运算符,以及按位非 (-bnot
) 。
从 PowerShell 2.0 开始,所有按位运算符都使用 64 位整数。
从 PowerShell 3.0 开始, -shr
引入了 (右移) 和 -shl
(左移) ,以支持 PowerShell 中的按位算术。
PowerShell 支持以下按位运算符。
运算符 | 说明 | 表达式 | 结果 |
---|---|---|---|
-band |
位与 | 10 -band 3 |
2 |
-bor |
按位或 (非独占) | 10 -bor 3 |
11 |
-bxor |
按位或 (独占) | 10 -bxor 3 |
9 |
-bnot |
按位“非” | -bNot 10 |
-11 |
-shl |
Shift-left | 102 -shl 2 |
408 |
-shr |
Shift-right | 102 -shr 1 |
51 |
按位运算符作用于值的二进制格式。 例如,数字 10 的位结构基于 1 字节) 00001010 (,数字 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, xfffffff5)
在按位左移运算中,所有位都向左移动“n”,其中“n”是右操作数的值。 零插入到零的位置。
当左操作数是整数 (32 位) 值时,右操作数的下 5 位将确定左操作数的位移位数。
当左操作数是一个 Long (64 位) 值时,右操作数的下 6 位将确定移动左操作数的位数。
表达式 | 结果 | 二进制结果 |
---|---|---|
21 -shl 0 |
21 | 0001 0101 |
21 -shl 1 |
42 | 0010 1010 |
21 -shl 2 |
84 | 0101 0100 |
在按位右移运算中,所有位都向右移动“n”,其中“n”由右操作数指定。 shift-right 运算符 (-shr) 在向右移动正值或无符号值时,在最左侧的位置插入零。
当左操作数是整数 (32 位) 值时,右操作数的下 5 位将确定左操作数的位移位数。
当左操作数是一个 Long (64 位) 值时,右操作数的下 6 位将确定移动左操作数的位数。
表达式 | 结果 | 二进制 | Hex |
---|---|---|---|
21 -shr 0 |
21 | 0001 0101 | 0x15 |
21 -shr 1 |
10 | 0000 1010 | 0x0A |
21 -shr 2 |
5 | 0000 0101 | 0x05 |
21 -shr 31 |
0 | 0000 0000 | 0x00 |
21 -shr 32 |
21 | 0001 0101 | 0x15 |
21 -shr 64 |
21 | 0001 0101 | 0x15 |
21 -shr 65 |
10 | 0000 1010 | 0x0A |
21 -shr 66 |
5 | 0000 0101 | 0x05 |
[int]::MaxValue -shr 1 |
1073741823 | 0x3FFFFFFF | |
[int]::MinValue -shr 1 |
-1073741824 | 0xC0000000 | |
-1 -shr 1 |
-1 | 0xFFFFFFFF |