BlackSheep-LSL@Wiki

演算子とは?

最終更新:

mizcremorne

- view
メンバー限定 登録/ログイン

演算子


まず最も基本的な演算子「=」について説明します。
「=」は「変数に代入する」という意味です。
つまり、

integer i = 100;

というのは
「iに」・・・何に
「100を」・・・何を
「代入する」・・・どうする
という処理になります。

「何に」「何を」という部分は変数もしくは定数になります。
「i」は整数型の変数ですし、「100」は値を直接指定した定数です。

「どうする」の部分が「=」ですが、「代入する」のように変数や定数を扱うための記号のことを「演算子(えんざんし)」と言います。

「=」は「代入演算子」と言い、「左側の変数に右側の変数の値または定数を代入」する演算子です。

単純な代入については変数のときにいくつか見てきましたので、少し応用した形をやってみましょう。
以下のような場合はどうなるでしょうか。

integer money1;
integer money2;
money1 = 100;
money2 = money1 + 50;

最後の行で、

money2 = money1 + 50;

money2に代入されるのは「money1の中身 + 50」です。
money1には100が代入されていますので、money2は100+50すなわち150になります。

「+」も演算子の一つで、「左側の変数・定数と右側の変数・定数を足す」演算子です。
算数で出てくる「+」とほぼ同じ動きをするのでそれほど難しくはないかと思います。

LSLに出てくる「+」は、算数の「+」と違い、文字列を足すこともできます。

string name1;
string name2;
name1 = "taro";
name2 = name1 + "imo";

name1には"taro"が代入されていて、name2には"taro" + "imo"が代入されますので、"taroimo"がname2の中身になります。

このように、演算子というのは、「+」とか「-」とか、計算を行うための記号のことです。
ほとんどは算数と同じですが、一部、プログラムに独特な考え方をするものもあります。

基本演算


最も基本的な演算子は、いわゆる四則演算をするものです。
以下に列挙してみます。

【基本的な演算子】
演算子 意味
+ 加算。足し算です
- 減算。引き算です
* 乗算。掛け算です
/ 除算。割り算です
% 余り。割り算した余りを計算します

  1. と-は算数と一緒ですね。
掛け算は×ではなく*になります。
割り算も÷ではなく/です。この/は分数の横棒のイメージですね(1/4=四分の一、すなわち1÷4)。
%は算数の÷に似ていますが、割り算ではなく余りの計算です。例えば、「10 % 3」ですと、10÷3の余り、1になります。

演算子は変数の型によって使えるものと使えないものがあります。
上記5つの演算子を全て使えるのは、integer型(整数型)の変数です。

integer money1 = 100;
integer money2;

money2 = money1 + 100;
money2 = money1 - 50;
money2 = money1 * 2;
money2 = money1 / 25;
money2 = money1 % 75;

上記は全てOKです。

float型(小数型)も四則演算は使えますが、小数には余りがありませんので、%(余り)は使用できません。

float speed1 = 0.5;
float speed2;

speed2 = speed1 + 1.0;
speed2 = speed1 - 0.25;
speed2 = speed1 * 1.5;
speed2 = speed1 / 0.1;

string型(文字列型)で使えるのは+だけです。
文字列型で+を使った場合は2つの文字列が連結されます。

string name1 = "pine";
string name2;

name2 = name1 + "apple";

上記の場合、name2には"pineapple"という文字列が入ります。

以下に演算子と型の関係をまとめました。

【同じ型同士の演算】
+ - * / %
Integer
Float
String
Vector
Rotation
List

少しややこしい話になりますが、vector型とrotation型の計算について説明しておきたいと思います。
数学はちょっと苦手・・・という方はサラリと読み飛ばしていただいて構いません。

まず復習ですが、vector型というのは3つの小数値がセットになっている型でした。

vector position = <10.5, 1.0, -5.6>;

これを便宜的に、<a, b, c>と表現することにします。
二つのvector型の変数、<a, b, c>と<d, e, f>があるとして、+、-、*、%の結果がどうなるのかを示します。

【vector型の演算】
結果 説明
<a, b, c> + <d, e, f> <a + d, b + e, c + f> 各要素ごとに加算する
<a, b, c> - <d, e, f> <a - d, b - e, c - f> 各要素ごとに減算する
<a, b, c> * <d, e, f> (a * d) + (b * e) + (c * f) ベクトルの内積(float型)
<a, b, c> % <d, e, f> <b * f - c * e, c * d - a * f, a * e - b * d> ベクトルの外積(vector型)

rotation型は以下のようになります。

【vector型の演算】
結果 説明
<a, b, c, d> + <e, f, g, h> <a + e, b + f, c + g, d + h> 各要素ごとに加算する
<a, b, c, d> - <e, f, g, h> <a - e, b - f, c - g, d - h> 各要素ごとに減算する
<a, b, c, d> * <e, f, g, h> 回転値の加算
<a, b, c, d> / <e, f, g, h> 回転値の減算

list型の+演算はリストの結合です。

list a = [1, 2, 3, 4];
list b = a + [5, 6, 7];

変数bの中身は[1, 2, 3, 4]と[5, 6, 7]が結合されて、 [1, 2, 3, 4, 5, 6, 7]になります。

異なる型同士での演算


演算子によっては、異なる型同士で計算が可能なものがあります。
例えば、以下のような場合です。

integer a = 10;
float b = a + 5.2;

この例では+演算子を使って整数型と小数型の値を加算しています。
整数と小数を加算した場合、結果は小数になります。

引き算でも同様のことが可能です。

integer a = 7;
float b = a - 2.4;

このように異なる型同士の計算ができるパターンはいくつかあります。

【異なる型同士の演算】
左辺 演算子 右辺 計算結果の型 備考
integer + float float
float + integer float
integer - float float
float - integer float
integer * float float
float * integer float
vector * integer vector <a,b,c> * d は <a*d, b*d, c*d>
vector * float vector <a,b,c> * d は <a*d, b*d, c*d>
vector * rotation vector 左辺vectoirを右辺rotationで示される回転値で回転させた結果
integer / float float
float / integer float
vector / float vector <a,b,c> / d は <a/d, b/d, c/d>
vector / integer vector <a,b,c> / d は <a/d, b/d, c/d>
vector / rotation vector 左辺vectoirを右辺rotationで示される回転値で逆回転させた結果

基本演算の応用


演算子を代入演算子と組み合わせて使うことができます。
代入演算子というのは「=」のことです。
しつこいようですが、これは「等しい」ではなく、「変数に値を代入する」という意味の演算子です。

スクリプトのコードを書いていると、時として、
  • 「ここで変数の値を10増やしたいんだよな~」
  • 「ここで変数の値を15減らしたいんだよな~」
  • 「ここで変数の値を2倍にしたいんだよな~」
  • 「ここで変数の値を半分にしたいんだよな~」
という状況になることがあります。

これを素直に書くと、

integer money = 100;
money = money + 10;
money = money - 15;
money = money * 2;
money = money / 2;

こんなふうになります。
moneyの値を足したり引いたり掛けたり割ったりして、もとの変数moneyに代入(値を書き換え)しています。
要するに、moneyの値を10増やしたり、15引いたり、二倍にしたり、半分にしたりしているわけです・・・。

これを簡単に書く方法があります。

integer money = 100;
money += 10;
money -= 15;
money *= 2;
money /= 2;

これらはそれぞれ、
  • moneyの値を10増やす(money += 10;)
  • moneyの値を15減らす(money -= 15;)
  • moneyの値を2倍にする(money *= 2;)
  • moneyの値を二分の一にする(money /= 2;)
ということになります。

また、こんな書き方もあります。

integer money = 100;
money ++;
money --;

これはそれぞれ、
  • moneyの値を1増やす
  • moneyの値を1減らす
という計算になります。
ループ処理などで、変数の値を1ずつ増やして処理したい場合などに登場しますので覚えておいて下さい。

論理演算


論理演算・・・などと言うと異様に難しそうな響きですが、LSLの論理演算は単に、
「正しいか、間違っているか」
の計算のことを言います。
「YesかNoか」
「真か偽か」
と言い換えてもいいでしょう。

これがどういうときに使われるかと言うと、
「タッチしたアバターがオーナーかどうか」
とか、
「支払われた金額が正しいかどうか」
などの判断を行うときに使われます。

論理演算は、必ず「正しい」か「間違っている」かのどちらかの値を返します。
「正しい」ときの値をTRUEと言います。
このTRUE、定数の章で出てきたのを覚えているでしょうか。
TRUEは整数値1とイコールです。

同様に「間違っている」ときの値をFALSEと言い、こちらは整数値0とイコールになります。
これも定数の一覧に載せてあります。

さて、簡単なのから見てみましょう。

【基本的な論理演算子】
演算子 意味 書き方 説明
== 等しいか? name == "miz" nameという変数の値が"miz"ならTRUE/そうでなければFALSE
!= 等しくないか? name != "miz" nameという変数の値が"miz"でないならTRUE/"miz"ならFALSE
< 小さいか? money < 100 moneyという変数の値が100より小さければTRUE/100以上ならFALSE
大きいか? money > 10 moneyという変数の値が10より大きければTRUE/10以下ならFALSE
<= 以下か? speed <= 1.0 speedという変数の値が1.0以下ならばTRUE/1.0より大きければFALSE
>= 以上か? speed >= 0.5 speedという変数の値が0.5以上ならばTRUE/0.5より小さければFALSE

「等しいかどうか」のときには「=」ではなく「==」を使いますので注意して下さい。
間違って「=」を使うと、エラーにならない上、ソフトバンク以上に想定外の動きをします。

上の例では、string型やinteger型、float型を使ってみましたが、「==」と「!=」は全ての型で使うことができます。
「<」「>」「<=」「>=」の4つは、integer型とfloat型でのみ使えます。
大小比較は数値じゃないとできませんので、当然と言えば当然ではあります。

ただし、list型で「==」「!=」を使った場合は、ちょっと判定基準が特殊です。
list型の「==」「!=」は、
「listに含まれる要素の数」
が比較されます。

従って、

[0,1,2,3] == [4,5,6,7,8] ・・・要素4つと要素5つなので等しくない、FALSE
["a","b"] == ["c","d"] ・・・どちらも要素2つなので等しい、TRUE
[0,1,2] != [3,4,5] ・・・どちらも要素3つなので等しい、FALSE
["a","b","c"] != ["d","e"] ・・・要素2つと要素3つなので等しくない、TRUE

要素の中身が何であろうと、要素数しか判断基準にしませんので注意して下さい。

論理演算の応用


さて・・・ここから難しくなってきます。
基本ではあるのですが、プログラミングに慣れていないと非常にわかりにくい世界に突入しますので、よくわからない場合はサラッと読み飛ばしていただいても構いません。

先ほどは単純な判定でしたが、もっと複雑な判定をしたい場合があります。
「タッチしたアバターがオーナーで、かつオブジェクトに座っている場合」とか。
「SIMが昼間か、または周囲に5人以上の人がいた場合」とか・・・。
そういう場合はどのようにするのでしょうか。

複数の判定条件がある場合は、それぞれに判定を行います。
それぞれの論理演算は結果的にTRUEかFALSEにしかなりませんので、あとはTRUEとFALSEの組み合わせで最終的な判定を行います。

判定条件が二つだった場合を想定して、どのように書くか見てみましょう。
仮に、一つ目の判定条件をA、二つ目の判定条件をBとします。
A,BはどちらもTRUEかFALSEの値になりますので、組み合わせは4通りです。
それぞれの値の組み合わせに対して、以下のような演算子で判定を行うことができます。

【論理演算の結合】
  • &&演算子(AND演算)
両方TRUEのときにTRUE/どちらか一方でもFALSEの場合はFALSE
  • A && Bの結果
Aの値 Bの値 結果
TRUE TRUE TRUE
TRUE FALSE FALSE
FALSE TRUE FALSE
FALSE FALSE FALSE

  • ||演算子(OR演算)
どちらか一方でもTRUEのときにTRUE/両方ともFALSEの場合はFALSE
  • A || Bの結果
Aの値 Bの値 結果
TRUE TRUE TRUE
TRUE FALSE TRUE
FALSE TRUE TRUE
FALSE FALSE FALSE

かなりややこしくなってきました・・・具体的に見てみましょう。

string型の変数nameが"miz"で、かつinteger型の変数countが10以上の場合にTRUEとする判定は・・・。

まず二つの判定を分けます。
「name == "miz"」

「count >= 10」
ですね。

両方ともがTRUEのときにTRUEとしたいので、 「&&」を使います。

(name == "miz") && (count >= 10)

このようになります。

さらに複雑にしてみましょう。

変数nameが"miz"で、かつ変数countが10以上の場合か、またはfloat型の変数speedが0.5より小さい場合にTRUEとする判定は・・・。

先ほどと同じく、
「name == "miz"」と「count >= 10」
これに加えて、
「speed < 0.5」
という判定が追加されます。

「変数nameが"miz"で、かつ変数countが10以上の場合」は、

(name == "miz") && (count >= 10)

こうでしたので、さらに、
「または変数speedが0.5より小さい場合」
を「||」でつなぎます。

( (name == "miz") && (count >= 10) ) || (speed < 0.5)

こんなふうに、()でくくって「&&」や「||」でつなげていくことで、複雑な判定を行うことができます。
()の位置には気をつけてください。
位置を間違えると、判定の意味は大きく変わってきます。

例えば・・・。

(name == "miz") && ( (count >= 10) || (speed < 0.5) )

これは先ほどの判定式と似ていますが、()の位置が異なります。
この判定はどのようなものになるかというと、

(name が "miz") かつ ( (count が 10以上) または (speed が 0.5より小さい) )

ですので、
「変数nameが"miz"の場合で、かつ、countが10以上かspeedが0.5より小さい場合」
にTRUEになります。

「&&」と「||」は、慣れると複雑な条件判定を一行で書けるのですが、判定式がたくさん出てくると非常にややこしくなってきますので、最初は二つの判定式をくっつけるところから練習すると良いかも知れません。

最後に、もう一つ論理演算子を紹介しておきます。
否定の演算子です。

!(name == "miz")
!(name != "miz")
!(count < 10)
!(count >= 5)

「!」は否定を意味します。
TRUEならばFALSE、FALSEならばTRUEを返す演算子です。

上記の例は、
!(name == "miz")・・・nameが"miz"と等し「くない」=nameが"miz"と異なる
!(name != "miz")・・・nameが"miz"と異な「らない」=nameが"miz"と等しい
!(count < 10)・・・countが10より小さ「くない」=countが10以上
!(count >= 5)・・・countが5以上「ではない」=countが5より少ない
ということになります。
記事メニュー
目安箱バナー