今回も前回に続いてbcコマンドです。前回はbcコマンドで簡単な計算を行いました。bcは簡単な計算だけでなくプログラム的な処理も行うことができます。実質プログラミング言語と比較しても遜色ないのでは?という感じもあります。
また、今回はPowerShellでの計算方法も説明します。ここでのPowerShellコマンドはWindows/macOS/UNIX用のいずれでも動作します。

PowerShellはとても簡単に計算できる

 PowerShellの場合、そのまま数式を入力するだけです。とても簡単です。というより、これ以上簡単にはできないでしょう。

1+2*3

 コマンドが冗長だったり面倒そうな感じもあるPowerShellですが、こと電卓計算に関しては素晴らしいと言えます。これぞ計算の得意なコンピューターといった感じです。
 もちろん括弧を使った計算もできます。

(1+2)*3

 簡単な計算だけでなく、より高度な計算もできます。例えば以下のようにコマンドを入力すると2の平方根が表示されます。ちなみにWindows PowerShell以外のmacOSのPowerShellなどでも問題なく計算されます。(bcの場合はsqrt()で計算できます)

[Math]::Sqrt(2)

べき乗を求めるならPow()が用意されています。以下のようにすると2の8乗の値である256が表示されます。

[Math]::Pow(2,8)

他にどのような計算ができるかは以下のマイクロソフト社のページを参照してください。

・Mathクラス
https://learn.microsoft.com/ja-jp/dotnet/api/system.math?view=net-7.0

bcで16進数計算する

 プログラミングで欠かせないのが16進数による計算です。計算は10進数でも結果を16進数で表示したい場合や、その逆も可能です。
 まず、計算結果を16進数で出力するようにしましょう。コマンドラインでbcと入力します。起動したらobase=16と入力します。

obase=16

 このように入力したら2+11と入力してみましょう。計算結果が16進数で表示されます。2+11は16進数ではDなので期待通りの結果になっています。

元に戻すにはobase=10と入力します。入力後に2+11と入力すると13と表示されます。

obaseはn進数で出力する値を指定しますので、結果を2進数で出力したい場合はobase=2のように指定します。

ここまではn進数で出力する場合でしたが、逆に入力をn進数にすることもできます。この場合はibaseを使います。16進数で計算した結果を10進数で出力する場合は以下のように指定します。

obase=10
ibase=16

ここでFF-10という16進数同士の計算をしてみましょう。以下のように入力すると16進数での計算結果が表示されます。

ibase=2とすれば2進数同士の計算もできます。以下のように入力すると2進数同士の計算が行われ結果が16進数で表示されます。

bcの機能

 bcの機能を知るにはmanコマンドを使えば表示されます。man bcと入力し下の方へ読んでいくと、このコマンドが予想以上に高機能であることがわかります。とは言っても簡単な計算がメインであれば、bcの高機能な部分は使うことはほとんどないでしょう。

man bc

 それではbcで三角関数の計算をしてみましょう。ここらへんはプログラマブル電卓というより関数電卓の範疇でしょう。ただし、bcコマンドで何も指定せずに三角関数の計算をしようとするとエラーになります。

三角関数の計算を行うにはbcコマンドでl(エル)オプションまたは--mathlibを指定する必要があります。Windowsのbcの場合は.¥bc.exe -lのようにオプションを指定します。なお、フォントによっては円記号は半角バックスラッシュで表示されます。以下の例はPowerShellからbc.exeを起動していますが、コマンドラインから起動する場合も同様です。なお、bc.exeのアイコンをダブルクリックして起動した場合は-lオプションなしの状態になります。

Windowsで-lオプションを付加した状態でbcを起動したい場合は以下のようにショートカットを作成しリンク先の欄の末尾に -lと入力します。あとは作成したbc.exeのショートカットから起動すればOKです。

三角関数の正弦(サイン/sin)はs()なので以下のようにすると計算結果が表示されます。()内には数値を指定しますが、この数値はラジアンになります。

s(1)

三角関数は他にも余弦(コサイン・cos)、逆正接(アークタンジェント・arctan)が用意されています。

・コサイン

c(1)

・アークタンジェント

a(0.5)

三角関数以外ではl()の自然対数、e()の指数関数、j()のベッセル関数が用意されています。

関数を定義して使う

 bcはプログラミング言語並みに高機能なので関数を定義したりループ/繰り返し処理を行うことができます。ここでは消費税の計算を行ってみましょう。これは単純に値に10%を乗算するだけです。このくらいなら関数を定義する必要もありませんが、現在の日本では消費税は8%と10%です。これら異なる税率にも対応させるために関数を定義してみましょう。
 bcで関数を定義するにはdefineの後に関数名とパラメーターを書きます。その後にブロック{}内に計算式や条件判断などの処理を書きます。
 消費税10%の場合を計算する関数taxは以下のように定義できます。

define tax(price){
 return (price*1.1)
}

それでは実際に定義した関数を使って計算してみましょう。定義した関数を使うには関数名(パラメーター)のように指定します。以下のようにすると100円に10%の消費税を加えた金額が表示されます。

tax(100)

続いて128円に10%の消費税を加えた金額を計算させてみましょう。

tax(128)

計算自体には間違いはありませんが・・・小数点以下の値まで表示されてしまうのはいまいちです。割り算の場合はscale=0とすれば整数値計算になりますが、掛け算の場合はそうはなりません。EXCELならINT(数値)で、JavaScriptなら数値|0ですが、bcでは少し工夫しなければいけません。
 bcはscale=0とした後に割り算を利用すると整数値にすることができるので、これを利用しましょう。ここで困るのがすでに設定されているscaleの値をどう保存すればよいか?という点です。都合が良いことにbcではプログラム言語と同じように変数を使うことができます。さらにローカル変数として定義することができます。このローカル変数は関数内でのみ有効なので他に定義されている関数内で使われている変数名と干渉しません。
 bcでローカル変数を定義するにはautoの後に変数名を書きます。複数まとめて定義する場合は,で区切って列記するだけです。
 変数に値を代入するには=を使います。ここらへんは一般的なプログラム言語(アルゴル系のプログラム言語。C言語やJava言語、Rust言語、Pythonなど)と同じです。

 先ほど定義したtax関数をscaleの値を保存しつつ整数値のみ表示するには以下のようになります。長くなりましたが、結果は問題ないようです。

define tax(price){
 auto old_scale
 old_scale=scale
 price=price*1.1
 scale=0
 price=price/1
 scale=old_scale
 return (price)
}

さて最後に軽減税率8%にも対応できるように関数を変更します。一般的なものの価格は正数です。これを利用して関数に負数が渡されたら軽減税率の8%での計算を行うようにします。bcには一般的なプログラム言語と同じ条件判断を行うifがあります。if()の括弧内に条件式を書きます。条件を満たした場合には以後に続く処理を実行します。複数の処理がある場合は{ }で囲みます。条件判断の等号・不等号はC言語(およびJava,Pythonなど)と基本的には同じです。どのような比較記号が使えるかはmac bcで表示されるマニュアルを参照してください。

 軽減税率を考慮した関数taxは以下のようになります。なお、bcでは同じ関数を何度も定義してもエラーにはなりません。また、関数を作成して挙動がおかしくなってしまった場合にはquitで一旦bcを終了させるのもよいでしょう。

define tax(price){
 auto old_scale,t
 old_scale=scale
 t=1.1
 if(price<0){
  price=price*-1
  t=1.08
 }
 price=price*t
 scale=0
 price=price/1
 scale=old_scale
 return (price)
}

bcはprintで文字列の出力もできます。以下のようにすると10%の消費税を加えた金額の後に円の文字が付加されます。

print tax(100),"円\n"

 bcは単なる計算コマンドではなく簡易プログラム言語みたいな使い方もできます。工夫次第では便利に使えるはずです。特にC言語などと違いコンパイルが不要で、ストレートに処理を入力していくこともできます。標準入力からも値などを読み込めるわけですから、ちょっとした処理ならbcでも代用できるシーンがあるかもしれません。

著者 仲村次郎
いろいろな事に手を出してみたものの結局身につかず、とりあえず目的の事ができればいいんじゃないかみたいな感じで生きております。