火曜日, 7月 24, 2007

math and physics

無事vj終えて、朝電車で帰ろうとすると、もう子供やら学生やらで溢れている。
夏休み始まってますーって感じだ。僕はまだ心の準備ができてない。

自転車で学校へ向かう途中、どっかの家の窓から子供に「おーい!バイバイー!」と声をかけられる。ハローグッバイ。

「夏休み?何言ってんの。毎日夏休みのくせに。」

と桂英史に言われたのはもう4年前。永過ぎる春は大物カップルも破局させるが永過ぎる夏(予備校含めたら6年)にはそれでもまだまだ山積みの宿題がある。

『ゲーム開発のための数学・物理学入門』を読み始める。ノートが一冊、余っていたのでそこに数式だのグラフだの書いて問題を解いてみることにする。別にゲーム作る訳じゃないけど。

読み始めていきなり、2のべき乗かどうかを判断するC++のプログラムはこんなんです、と出てきた。

bool powOfTwo(int num) {
return !(num&(num-1));
}

まぁここは関数の便利さとか、数学とプログラミングの関係を説明するためだったのでさらっと読み飛ばすとこなんだけど、このアルゴリズムが気になってしまった。
何である整数から1を引いたものを&で比較したらtrueだのfalseだのがわかるんだ?そもそも&って何?

試しにprocessingで上記のコードを書いてみる。

void setup() {
println(powOfTwo(4));
}

boolean powOfTwo(int num) {
return !(num&(num-1));
}

実行すると、

Semantic Error: The type of this expression, "int", is not "boolean".

というエラー。int型で比較してそのままboolean型を返すのはできないみたい。
で、どんな値になってるか調べてみる。

void setup() {
powOfTwo(4);
}

void powOfTwo(int num) {
println(num&(num-1));
}

実行すると、0が出力される。powOfTwoに渡す数値を色々変えて試すと、2のべき乗の時に0になる。
一体これは何なんだと思って、まず&が何やってんのかを調べる。wikipedia先生ー。

「数理論理学において論理積(ろんりせき、合接(ごうせつ) 連言)とは、与えられた複数の命題のいずれもが例外なく真であることを示す論理演算である。ANDとも表す。」

ということで、trueとtrueの場合、true。trueとfalseの場合、false。falseとfalseの場合、false。
trueが1で、falseが0の掛け算。

ここまできて、受け取った整数を2進数にして、1引いた数と比較してるってことがわかった。
えーと、2の2乗である4の場合、100でそっから1引いた3は11。0をつめてやると011。なので、100と011の各桁を比べて、1と0で0、0と1で0、0と1で0。

となり、0になる。8は1000で7は0111だし、以後そんな感じ。2のべき乗から1引いて論理積求めると、必ず0になる。多分C++だとそのまま0がfalseになるので、「2のべき乗のときはtrueを返す」ということで!で反転させてreturnしているんだろう。

こういう基本的なとこわかってないから苦労する。2進数と10進数をさらっと変換できないし。

その後は割と普通に1次方程式の傾きとか求めたり、中学高校の復習って感じ。サンプルコードをp5に書き換えたりして遊んでる。それもいずれupしようと思う。

ちなみに2のべき乗を判定するのはこうかな。

void setup() {
println(powOfTwo(4));
}

boolean powOfTwo(int num) {
int x = num&(num-1);
if(x==0) return true;
else return false;
}

0 件のコメント: