算術演算

ここでは、値や変数に対して、四則演算などの算術演算を行う方法を扱います。

- 目次 -

算術演算子

プログラムは、コンピューターに様々な計算処理を行わせるためのものです。 変数に対して計算処理を行うためには、算術演算子を記述します。 VCSSLでサポートしている算術演算子には、以下の種類があります。

記号 意味 扱える型 詳細
 + 加算
(足し算)
int,
float,
complex,
varint,
varfloat,
varcomplex,
string
数値を足す演算です。string型に対しては例外で、文字列を接続する演算となります。
 - 減算
(引き算)
int,
float,
complex,
varint,
varfloat,
varcomplex
数値を引く演算です。
 * 乗算
(掛け算)
int,
float,
complex,
varint,
varfloat,
varcomplex
数値を掛ける演算です。
 / 除算
(割り算)
int,
float,
complex,
varint,
varfloat,
varcomplex
数値を割る演算です。
 % 剰余算
(余り)
int,
varint
数値を割った余りを求める演算です。
 ** 指数
(冪乗)
float,
varfloat
指数演算です。
※ 使用するには、Mathライブラリをインポートする必要があります。

※ 指数演算について

指数演算は、VCSSL2.1以前では「^」記号が割り当てられていましたが、この記号は他のC言語系言語では排他的論理和(XOR)を意味する事から、VCSSL2.1以降では代わりに「**」記号の使用が推奨されるようになりました。

また現時点では、整数同士の指数演算は、少数型に変換されてから実行されるため、結果が小数になります。この事は混同を招くため、VCSSL3.0以降で整数同士の指数演算は非推奨となり、小数型に明示的にキャストしてから演算する事が推奨されるようになりました。

整数同士の指数演算は、当面の間は互換性が維持されますが、将来的には整数の結果を返すように仕様が修正される可能性があります。

複合演算子と特殊な演算子

演算と同時に代入する(複合代入演算子)など、使用頻度の多い演算に対しては、 以下のように特別な演算子が用意されています。この演算子は多くのC言語系の言語においても採用されているものです。

記号 意味 使用例
 += 左の値に、右の値を足して、それを左の値に代入する a += b ;
( aにはa+bの結果が代入される )
 -= 左の値に、右の値を引いて、それを左の値に代入する a -= b ;
( aにはa-bの結果が代入される )
 *= 左の値に、右の値を掛けて、それを左の値に代入する a *= b ;
( aにはa*bの結果が代入される )
 /= 左の値に、右の値を割って、それを左の値に代入する a /= b ;
( aにはa/bの結果が代入される )
 ++ 左か右の値に1を足して、結果をその値に代入する a ++ ;
( aにはa+1の結果が代入される )
 -- 左か右の値に1を引いて、結果をその値に代入する a -- ;
( aにはa-1の結果が代入される )

最後の2 つの演算子は、ループのカウンタ制御で用いるため、使用頻度が非常に高くなります。 このため、一般に「++」演算にはインクリメント、 「--」演算にはデクリメントという呼称が付いています。

インクリメント(とデクリメント)は、変数の前にも後にも記述できます。 前者を前置インクリメント、後者を後置インクリメントと呼びます。 インクリメント結果を同じ式中で別の変数に代入するような場合、 前置インクリメントでは加算後の値が、後置インクリメントでは加算前の値が代入されます。

加算を行う

例として、加算を行ってみましょう。以下のように記述してみてください:

Add1To1.vcssl

- 実行結果 -

2

このプログラムを実行すると、VCSSLコンソールに「 2 」が表示されます。これを以下のようにするとどうなるでしょう:

Add1To1.vcssl

- 実行結果 -

2.0

今度は、メッセージウィンドウに 2.0 が表示されます。

上の例では 2 と整数だったのが、 下の例では2.0 と小数になりました。 これは、最初の演算の結果は整数値となり、後の演算の結果は小数値となった事を意味しています。

このように、算術演算結果の型は、演算対象の値の型によって異なります。

具体的には、整数同士の演算結果は整数になります。 そして、小数同士の場合と、整数と小数の混合演算の場合は、小数型の値になります。

これを表にすると以下のようになります:

AとBの演算結果 A=整数 A=小数
B=整数 AとBの演算結果
=整数
AとBの演算結果
=小数
B=小数 AとBの演算結果
=小数
AとBの演算結果
=小数

さらに同じようにして、複素数を含む混合演算は複素数になります。 つまり上の表に複素数を加えると、以下のようになります。

AとBの演算結果 A=整数・小数 A=複素数
B=整数・小数 AとBの演算結果
=上の表
AとBの演算結果
=複素数
B=複素数 AとBの演算結果
=複素数
AとBの演算結果
=複素数

(重要)整数同士の除算には注意が必要

上の規則は、除算、つまり割り算の場合に注意が必要です。

一般に整数同士の加減算と乗算の結果は、数学的にも整数なので、何も問題はありません。 しかし整数同士の除算はそうではありません。 にもかかわらず、整数同士の乗算結果は必ず整数として返されてしまうわけです。 このために、慣れるまで厄介な落とし穴が生じます。

例えば、以下のようにしてみてください:

Div1By2.vcssl

- 実行結果 -

0

これを実行すると、 0 が表示されます。

数学的には 0.5 となるべきなのですが、これが整数に変換されて 0 となってしまったのです。 このような振る舞いはVCSSLに限らず、様々な言語においても見られるものです。

正しい(小数の)答えを得るには、以下のように小数へキャストしてから演算してください。

Div1By2Cast.vcssl

- 実行結果 -

0.5

これを実行すると、正しい答えである 0.5 が表示されます。

変数ではなく値を直接演算する場合は「 .0 」を付けて小数にしても良いでしょう:

Div1fBy2f.vcssl

- 実行結果 -

0.5

これも正しく 0.5 を表示します。しかし、変数に「 .0 」を付けてもキャストはされないので注意してください。

演算順序の指定

複数の演算を行う場合、演算の順序が問題となります。例えば、以下のような場合を考えてみましょう:

Add1To2Mul3.vcssl

- 実行結果 -

7

こういった場合、加算・減算よりも、乗算・除算のほうが先に計算されます。 つまり、2*3=6の値が、1に足されて、結果は 7 が出力されます。

1+2を先に計算させたいなら、次のように ( ) で囲みます:

Add1To2Mul3Bracket.vcssl

- 実行結果 -

9

こうすれば、1+2=3が先に計算され、それに3が掛けられて、結果は 9 が出力されます。

算術演算子の優先度

異なる演算子が混在する式の場合、優先度の高い演算子から先に処理されます。優先度は、以下の順で設定されています。

- 算術演算子の優先度 -

 冪乗算 > 剰余算 = 除算 = 乗算 > 減算 = 加算

つまり乗算や除算は、加算や減算よりも優先度が高く、先に処理されます。なお、乗算と除算のように、 同じ優先度の演算子が並んでいる場合は、左から順に処理されます。

文字列の加算

ところで、string型の値については、他の型とは算術演算子の挙動が大きく異なります。まず、string型には加算以外の演算が行えません。 また、string型と他の型との加算は、演算対象をすべてstring型に変換した上で行われます。

例えば、以下の例を実行してみてください。

AddStringToInt.vcssl

- 実行結果 -

12

これを実行すると、 12 が表示されます。これは「 "1" という文字列と "2" という文字列を接続せよ 」 という処理となったためです。