about_Arithmetic_Operators

簡単な説明

PowerShell で算術演算を実行する演算子について説明します。

詳細な説明

算術演算子は数値を計算します。 1 つ以上の算術演算子を使用して、値を加算、減算、乗算、除算し、除算演算の再メインダー (剰余) を計算できます。

加算演算子 (+) と乗算演算子 (*) は、文字列、配列、ハッシュテーブルでも動作します。 加算演算子は入力を連結します。 乗算演算子は、入力の複数のコピーを返します。 算術ステートメントでは、オブジェクト型を混在させることができます。 ステートメントの評価に使用されるメソッドは、式の左端のオブジェクトの型によって決まります。

PowerShell 2.0 以降では、すべての算術演算子が 64 ビット数値で動作します。

PowerShell 3.0 以降では、 -shr PowerShell でビットごとの算術演算をサポートするために (shift-right) と -shl (shift-left) が追加されています。 ビット演算子は整数型でのみ機能します。

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
    
  • 剰余 (%) - 除算演算の reメインder を返します。

    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 は、算術演算子を次の順序で処理します。

優先順位 Operator 説明
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が変更されます。 次の変数$aは等しく1、ありません0$b[$a] したがって、ステートメントは値を $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

結果の型がオペランドの 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

ただし、結果[double][ulong]範囲を超えると、

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

Bigint 算術

数値に対して [bigint] 算術演算を実行すると、PowerShell ではすべてのオペランド [bigint]が変換され、整数以外の値が切り捨てられます。 たとえば、値1.9[double]変換時[bigint]1切り捨てられます。

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

この動作は、他の数値型の動作とは異なります。 この例では、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 演算子 (および-bxor)、ビットごとの NOT (-bnot-band-bor) など、標準のビットごとの演算子がサポートされています。

PowerShell 2.0 以降では、すべてのビット演算子が 64 ビット整数で動作します。

PowerShell 3.0 以降では、 -shr PowerShell でビットごとの算術演算をサポートするために、(shift-right) と -shl (shift-left) が導入されています。

PowerShell では、次のビット演算子がサポートされています。

Operator 説明 Expression 結果
-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 のビット構造は (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 の場所に挿入されます。

Expression 結果 バイナリ結果
21 -shl 0 21 0001 0101
21 -shl 1 42 0010 1010
21 -shl 2 84 0101 0100

ビットごとのシフト右演算では、すべてのビットが "n" の位置を右に移動します。ここで、"n" は右オペランドで指定されます。 shift-right 演算子 (-shr) は、符号付き値をシフトするときに、符号ビットを左端にコピーします。 符号なし値の場合、左端の位置に 0 が挿入されます。

Expression 結果 バイナリ 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

関連項目