次の方法で共有


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は、 ではなく 01等しくなります。 したがって、 ステートメントは ではなく $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

こちらもご覧ください