Bash での算術演算
算術式
((...)) 構文は、整数に対して算術演算を実行できます。
$ ((foo = 5 + 5))
$ echo $foo
10
((...)) は内部スペースを自動的に無視するため、以下の記述方法は正しく、同じ結果が得られます。
$ ((2+2))
$ (( 2+2 ))
$ (( 2 + 2 ))
この構文は値を返しません。コマンドの実行結果は算術演算の結果によって決まります。演算結果が「0」でない限り、コマンドは正常に実行されます。
$ (( 3 + 2 ))
$ echo $?
0
上の例では、「3 + 2」の結果は 5 です。コマンドが正常に実行された場合でも、環境変数「$?」は「0」です。
算術結果が「0」の場合、コマンドは失敗します。
$ (( 3 - 3 ))
$ echo $?
1
上記の例では、「3 - 3」の結果は「0」、環境変数「$?」は「1」となり、コマンドの実行が失敗したことを示しています。
算術演算の結果を読みたい場合は、「((...))」の前にドル記号「$((...))」を追加して算術式に変換して返す必要があります。算術演算の値。
$ echo $((2 + 2))
4
((...)) 構文でサポートされる算術演算子は次のとおりです。
+: 追加-: 減算*: 乗算/: 除算(割り算可能)%: 余り**: インデックス++: インクリメント演算 (プレフィックスまたはサフィックス)--: デクリメント演算 (プレフィックスまたはサフィックス)
たとえば、「5」を「2」で割った場合、結果は「2.5」ではなく「2」になることに注意してください。
$ echo $((5 / 2))
2
2 つの演算子 ++ と -- には接頭辞と接尾辞があります。接頭辞の場合、最初に操作が実行されてから値が返されます。接尾辞の場合、最初に値が返されてから操作が実行されます。
$ i=0
$ echo $i
0
$ echo $((i++))
0
$ echo $i
1
$ echo $((++i))
2
$ echo $i
2
上の例では、サフィックスとして ++ を指定すると、最初に値が返され、echo コマンドが実行され、次にプレフィックスとして自動インクリメント操作が実行され、次に値が返されます。そして「echo」コマンドを実行します。
$((...)) 内で括弧を使用すると、演算の順序を変更できます。
$ echo $(( (2 + 3) * 4 ))
20
上記の例では、内側の括弧により、乗算の前に加算が実行されます。
$((...)) 構造はネストできます。
$ echo $(((5**2) * 3))
75
$ echo $(($((5**2)) * 3)) # に相当
75
この構文は整数のみを計算できます。それ以外の場合はエラーが報告されます。
# エラーを報告する
$ echo $((1.5 + 1))
bash: 構文エラー
$((...)) の括弧内では、変数名の前に $ を追加する必要はありませんが、追加してもエラーは報告されません。
$ number=2
$ echo $(($number + 1))
3
上記の例では、変数番号の前にドル記号があってもなくても、結果は同じです。
$((...)) 内で文字列を使用すると、Bash はそれを変数名とみなします。同じ名前の変数が存在しない場合、Bash はそれを null 値として扱うため、エラーは報告されません。
$ echo $(( "hello" + 2))
2
$ echo $(( "hello" * 2))
0
上の例では、"hello" は変数名とみなされ null 値が返されますが、$((...)) は null 値を 0 として扱うため、次の結果が返されます。乗算は 0 です。同様に、$((...))に存在しない変数を使用した場合も0として扱われます。
変数の値が文字列の場合、処理ロジックは上記と同じです。つまり、文字列が既存の変数に対応しない場合、$((...)) では null 値として扱われます。
$ foo=hello
$ echo $(( foo + 2))
2
上記の例では、変数 foo の値は hello であり、hello も変数名とみなされます。これにより、動的に置き換えられるコードを書くことが可能になります。
$ foo=hello
$ hello=3
$ echo $(( foo + 2 ))
5
上記のコードでは、foo + 2 は変数 hello の値に依存します。
最後に、$[...] は以前の構文ですが、整数演算にも使用できますが、お勧めできません。
$ echo $[2+2]
4
数値の底
Bash の値はデフォルトでは 10 進数ですが、算術式では他の基数も使用できます。
number: 特別な表現のない数値は 10 進数 (基数 10) です。0number: 8 進数。0xnumber: 16 進数。base#number:baseの基本番号。
以下にいくつかの例を示します。
$ echo $((0xff))
255
$ echo $((2#11111111))
255
上面例子中,0xff是十六进制数,2#11111111是二进制数。
ビット演算
$((...)) は次の 2 進ビット演算子をサポートします。
<<: ビット左シフト演算。数値のすべてのビットを指定されたビットだけ左に移動します。>>: ビット右シフト演算。数値のすべてのビットを指定されたビットだけ右に移動します。&: ビットごとの AND 演算。2 つの数値のすべてのビットに対してAND演算を実行します。|: ビットごとの OR 演算。2 つの数値のすべてのビットに対してOR演算を実行します。~: ビットごとの「いいえ」演算。数値のすべてのビットを反転します。^: ビット単位の排他的 OR 演算 (排他的論理和)。2 つの数値のすべてのビットに対して排他的 OR 演算を実行します。
以下は右シフト演算子「>>」の例です。
$ echo $((16>>2))
4
以下は左シフト演算子「<<」の例です。
$ echo $((16<<2))
64
以下は、「17」 (バイナリ「10001」) と「3」 (バイナリ「11」) に対するさまざまなバイナリ演算の結果です。
$ echo $((17&3))
1
$ echo $((17|3))
19
$ echo $((17^3))
18
論理演算
$((...)) は次の論理演算子をサポートします。
<: より小さい>: より大きい<=: 以下>=: 以上==: 等しい!=: 等しくない&&: 論理積||: 論理和!: 論理いいえexpr1?expr2:expr3: 三項条件演算子。式expr1がゼロ以外の値 (算術 true) に評価された場合は、式expr2が実行され、それ以外の場合は式expr3が実行されます。
論理式が真の場合は「1」を返し、それ以外の場合は「0」を返します。
$ echo $((3 > 2))
1
$ echo $(( (3 > 2) || (4 <= 1) ))
1
三項演算子は、単一の論理テストを実行します。これは「if/then/else」ステートメントのように機能します。
$ a=0
$ echo $((a<1 ? 1 : 0))
1
$ echo $((a>1 ? 1 : 0))
0
上の例では、最初の式が true の場合は 2 番目の式の値が返され、それ以外の場合は 3 番目の式の値が返されます。
代入演算
算術式 $((...)) は代入演算を実行できます。
$ echo $((a=1))
1
$ echo $a
1
上の例では、「a=1」は変数「a」に値を代入します。この数式自体も式であり、戻り値は等号の右側の値になります。
$((...)) でサポートされる代入演算子には次のものがあります。
parameter = value:単純な割り当て。parameter += value:parameter = parameter + value。parameter -= value:parameter = parameter – valueに相当。parameter *= value:parameter = parameter * valueに相当。parameter /= value:parameter = parameter / valueに相当。parameter %= value:parameter = parameter % valueに相当。parameter <<= value:parameter = parameter << valueに相当。parameter >>= value:parameter = parameter >> valueに相当。parameter &= value:parameter = parameter & valueに相当。parameter |= value:parameter = parameter | valueに相当。parameter ^= value:parameter = parameter ^ valueに相当。
以下に例を示します。
$ foo=5
$ echo $((foo*=2))
10
式内で値を割り当てる場合は、括弧で囲むことができます。そうしないと、エラーが報告されます。
$ echo $(( a<1 ? (a+=1) : (a-=1) ))
評価操作
$((...)) 内のコンマ , は評価演算子で、前後 2 つの式を実行し、後者の式の値を返します。
$ echo $((foo = 1 + 2, 3 * 4))
12
$ echo $foo
3
上記の例では、カンマの前後の両方の式が実行され、後者の式 12 の値が返されます。
expr コマンド
expr コマンドは算術演算をサポートしており、((...)) 構文を使用する必要はありません。
$ expr 3 + 2
5
expr コマンドは変数置換をサポートしています。
$ foo=3
$ expr $foo + 2
5
expr コマンドも非整数の引数をサポートしません。
$ expr 3.5 + 2
expr: 非整数参数
上記の例では、非整数演算がある場合、expr コマンドはエラーを報告します。
let コマンド
「let」コマンドは、算術演算の結果を変数に代入するために使用されます。
$ let x=2+3
$ echo $x
5
上の例では、変数 x は 2+3 の結果と等しくなります。
数式「x=2+3」にはスペースを含めることはできません。スペースを含めるとエラーが報告されます。 「let」コマンドの詳細な使用法については、「変数」の章を参照してください。
作者: wangdoc
アドレス: https://wangdoc.com/
ライセンス: クリエイティブ・コモンズ 3.0