about_Arithmetic_Operators
簡単な説明
PowerShell で算術演算を実行する演算子について説明します。
長い説明
算術演算子は数値を計算します。 1 つ以上の算術演算子を使用して、値を加算、減算、乗算、除算し、除算演算の剰余 (剰余) を計算できます。
加算演算子 (+
) と乗算演算子 (*
) は、文字列、配列、ハッシュテーブルでも動作します。 加算演算子は入力を連結します。
乗算演算子は、入力の複数のコピーを返します。 算術ステートメントでオブジェクト型を混在させることさえできます。 ステートメントの評価に使用されるメソッドは、式の左端のオブジェクトの型によって決まります。
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++]
で 使用された後、 で使用$b[$a]
される前に の値$a
が変更されます。 の$b[$a]
変数$a
は、 ではなく 0
と1
等しくなります。 したがって、 ステートメントは ではなく $b[0]
に値を$b[1]
割り当てます。
上記のコードは、次のコードと同じです。
$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
結果の型がオペランドの 1 つと常に同じとは限りません。 次の例では、負の値を符号なし整数にキャストすることはできません。符号なし整数が大きすぎて に 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.
精度の損失の可能性
型の範囲を超える結果が生じると、型変換によって精度が低下するリスクがあります。 たとえば、 を十分に大きく [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
ただし、 の [ulong]
範囲を超えると、 になります [double]
。
PS> ([ulong]::MaxValue + 1).GetType().FullName
System.Double
Bigint 算術
数値に対して [bigint]
算術演算を実行すると、PowerShell はすべてのオペランドを に [bigint]
変換します。これにより、整数以外の値が切り捨てられます。 たとえば、 に変換[bigint]
すると、[double]
値1.9
は に1
切り捨てられます。
PS> [bigint]1 / 1.9
1
PS> 1 / [bigint]1.9
1
この動作は、他の数値型の動作とは異なります。 この例では、 を [int]
で除算すると [double]
、 になります [double]
。 にキャスト 1.9
すると [int]
、値が に 2
丸め込まれます。
PS> 1 / 1.9
0.526315789473684
PS> 1 / [int]1.9
0.5
数値以外の型の追加と乗算
数値、文字列、配列、ハッシュ テーブルを追加できます。 また、数値、文字列、配列を乗算できます。 ただし、ハッシュ テーブルを乗算することはできません。
文字列、配列、またはハッシュ テーブルを追加すると、要素が連結されます。 配列やハッシュ テーブルなどのコレクションを連結すると、両方のコレクションのオブジェクトを含む新しいオブジェクトが作成されます。 同じキーを持つハッシュ テーブルを連結しようとすると、操作は失敗します。
たとえば、次のコマンドでは、2 つの配列を作成し、それらを追加します。
$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
次の例では、キーの 1 つが両方のハッシュ テーブルで重複しているため、エラーがスローされます。
$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
評価とコマンドレット式の評価を 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 では、ビットごとの AND ()、包括的および排他的なビットごとの OR 演算子 (-bor
と -bxor
)、ビットごとの NOT (-band
-bnot
) など、標準のビットごとの演算子がサポートされています。
PowerShell 2.0 以降では、すべてのビットごとの演算子が 64 ビット整数で動作します。
PowerShell 3.0 以降では、 -shr
PowerShell でビットごとの算術演算をサポートするために、 (shift-right) と -shl
(shift-left) が導入されています。
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 |
Shift キーを押しながら左へ移動 | 102 -shl 2 |
408 |
-shr |
Shift キーを押しながら右方向に移動 | 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 の場合にのみ 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" は右オペランドの値です。 0 が 1 の場所に挿入されます。
正規表現 | 結果 | バイナリの結果 |
---|---|---|
21 -shl 0 |
21 | 0001 0101 |
21 -shl 1 |
42 | 0010 1010 |
21 -shl 2 |
84 | 0101 0100 |
ビットごとのシフト右演算では、すべてのビットが "n" の場所を右に移動します。ここで、"n" は右オペランドで指定されます。 shift-right 演算子 (-shr
) は、符号付き値をシフトするときに、符号ビットを左端にコピーします。 符号なし値の場合、左端の位置に 0 が挿入されます。
正規表現 | 結果 | 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 |