破棄されたブログ

このブログは破棄されました。

ビット演算の使い道

この記事 2013-04-06 - がるの健忘録 を読んで以来、一生ビット演算なんかとは縁がないまま死んでいくんだろうなとか思ってた矢先に使い道を思いついたんでメモ。揉め。

<?php
// 環境定義
define('ENV_DEVELOP',    0x1);
define('ENV_TEST',       0x2);
define('ENV_PRODUCTION', 0x4);

// 環境設定
define('ENV', ENV_DEVELOP);
printf("%08b\n", ENV); // 0001

// 開発環境のみ
printf("%08b\n", ENV_DEVELOP & ENV); // 0001
// 開発環境もしくはテスト環境
printf("%08b\n", (ENV_TEST | ENV_DEVELOP) & ENV); // 0001
// 開発環境以外
printf("%08b\n", ~ ENV_DEVELOP & ENV); // 0000
?>


運用環境を定数で定義しておいて、環境固有の処理を振り分けるのにいいと思う。
利点は色々と思いつく。

フラグ毎に定数を持たせると、すべてのフラグが並列になっていまう。

<?php
define('IS_DEVELOP'   , TRUE);
define('IS_TEST'      , FALSE);
define('IS_PRODUCTION', TRUE); // どっち
?>

こういう書き方だと、IS_DEVELOP と IS_PRODUCTION が両方 TRUE になっているみたいなオカシナ状態にもなりうる。

フラグを統一した場合、ビット演算を使わないことによるメリットが思いつかない。

<?php
define('ENV_DEVELOP'   , 'DEVELOP');
define('ENV_TEST'      , 'TEST');
define('ENV_PRODUCTION', 'PRODUCTION');

define('ENV', ENV_DEVELOP);

// 開発環境もしくはテスト環境
if ((ENV === ENV_DEVELOP)
    || (ENV === ENV_TEST)
) {
    // do something
}
?>

こんな事をするなら、普通にビット使えばいい。定数 /^ENV_[A-Z]$/ は、値をバラバラにしないといけない。それなら普通に 16 進数で表記するのとコスト的にもなにも変わらないハズ。それに、条件分岐するときの表記が冗長になる。

桁に意味を持たせられる

<?php
// 環境定義
define('ENV_DEVELOP',    0x11);
define('ENV_TEST',       0x20);
define('ENV_TEST1',      ENV_TEST | 0x01);
define('ENV_TEST2',      ENV_TEST | 0x02);
define('ENV_PRODUCTION', 0x41);

// 環境設定
define('ENV', ENV_TEST1);
printf("%08b\n", ENV); // 00100001

// テスト環境 1 だけ
printf("%08b\n", ENV_TEST1 & ENV); // 00100001
// 任意のテスト環境
printf("%08b\n", ENV_TEST & ENV & 0xF0); // 00100000, & 0xF0 でフィルタ
?>

テスト環境が複数あるような場合、上位桁は環境種別、下位桁はシーケンシャルな番号とかにしてやる。特定のテスト環境だけとか、任意のテスト環境でとかそういう振り分けも出来るようになる。

あとは、関数・メソッドの引数にフラグを複数渡さないといけない時、ビット演算を使えば、ひとつで引数にまとめてフラグを渡すことができるとか。

追記

珈琲フロートとか、液体の部分の上にアイスクリームとかホイップクリームとかのってる飲み物ってすごく美味しそうでよく飲むんだけど、いざ飲もうと思うと邪魔だし、結局スプーンとかストローとかで混ぜちゃうから、最初から混ざってるのと変わらないよね。

広告を非表示にする