バッチファイルで数式を扱う

Windowsのcmd.exeでは、setコマンドに「/a」オプションを指定することで数式を評価できます。この機能がどのようなものか、確認してみました。*1

はじめに

概要

cmd.exeでは、「set /a 式」とすることにより、数式を評価できます。*2 また、評価結果を環境変数にセットすることも可能です。詳細は、「set /?」を参照してください。

演算子について

式の中では、C言語ライクな演算子を使って、四則演算やビット演算を行うことができます。また、複合代入演算子も使えます。比較演算子(==, !=, >, >=, <, <=)、インクリメント(++)、デクリメント(--)、論理AND(&&)、論理OR(||)は使えないようです。

注意点

いくつか注意点を書いておきます。

  • 「set /a」は、コマンドラインとコマンドスクリプト(バッチファイル)で一部の挙動が異なる。*3
    • コマンドラインでは、評価した式の値を、標準出力に出力する。*4
    • コマンドスクリプトでは、評価した式の値が自動的に出力されることはない。
  • 式の中で環境変数を使う場合は、%で囲む必要はない。(囲んでも良い。)
  • 扱う値は、符号付き32ビット整数のみである。小数は扱うことができない。
  • 式は二重引用符で囲んでおくのがよい。そうでないと、シフト演算子などの一部の演算子でエスケープが必要になる。
  • 評価した式の値は、環境変数にセットして使用する。
  • if文の条件部の中で直接使うようなことはできない。

テスト

バッチファイルを作成し、いろいろな式をテストしてみました。(バッチファイルの先頭で「@echo off」としていますが、下記のコードでは省略しています。)

テスト1 (四則演算)

四則演算のテストです。計算結果を環境変数X、Y、Zに代入し、その値をechoで表示します。モジュロ演算子(剰余演算子)の「%」は、バッチファイルなので「%%」となります。

set /a "X = (5 + 3) * (7 - 2), Y = X / 11, Z = X %% 11"
echo X=%X%, Y=%Y%, Z=%Z%
X=40, Y=3, Z=7
テスト2 (未定義の環境変数)

未定義の環境変数を使った場合のテストです。式を評価する前に、環境変数Xを明示的にクリアしています。式の中で未定義の環境変数が現れた場合、値が0であるものとして扱われます。

set X=
set /a "X = X + 100"
echo X=%X%
X=100
テスト3 (16進表記と8進表記)

16進表記と8進表記のテストです。0xで始まる数値は16進数、0で始まる数値は8進数として評価されます。

set /a "X = 0x0034, Y = 012"
echo X=%X%, Y=%Y%
X=52, Y=10
テスト4 (複合代入演算子)

複合代入演算子のテストです。

set /a "X = 5, X += 1, X -= 2, X *= 3, X /= 4"
echo X=%X%
X=3
テスト5 (論理否定)

論理否定のテストです。0の場合は1、非0の場合は0になります。

set /a "X = !0, Y = !1, Z = !2"
echo X=%X%, Y=%Y%, Z=%Z%
X=1, Y=0, Z=0
テスト6 (1の補数、ビットごとのAND)

1の補数演算(ビット反転)のテストです。ついでに、ビットごとのANDもテストしています。

rem ~0x35 = ~0b00110101 = 0b11001010 = 202 (8ビット計算)
set /a "X = ~0x35 & 0xFF"
echo X=%X%
X=202
テスト7 (左シフト、ビットごとのOR)

左シフトのテストです。ついでに、ビットごとのORもテストしています。

rem 0b00101010 = 42
set /a "X = 1 << 1 | 1 << 3 | 1 << 5"
echo X=%X%
X=42
テスト8 (右シフト)

右シフトのテストです。ヘルプを見ると論理シフトと書いてありますが、実際は算術シフトのようです。

set /a "X = 0x000000FF >> 4, Y = 0xFFFFFF00 >> 1"
echo X=%X%, Y=%Y%
X=15, Y=-128
テスト9 (ビットごとの排他的論理和)

ビットごとの排他的論理和(XOR)のテストです。

rem 0xAB = 0b10101011
rem 0xCD = 0b11001101
rem 0xAB ^ 0xCD = 0b01100110 = 102
set /a "X = 0xAB ^ 0xCD"
echo X=%X%
X=102
その他
  • 式の表記は、C言語の式のサブセットと考えてよさそう。
  • バッチファイルでの有効な使い道があまり思いつかない。

*1:Windows XP SP3で確認しました。

*2:aはarithmeticの略だと思います。

*3:こういうのは、やめてほしい…。

*4:コンマ区切りで複数の式を指定した場合は、最後の式の値のみが出力されます。