TOP >> マニアックなプログラミング
トリッキーコードネット トリッキーなコード

【トリッキーなコード】剰余演算(mod)をトリッキーに

呼ばれて飛び出てジャジャジャジャーン!!
え~っと、ちょっと遊び心満載の話題を提供してみます (* ̄ー ̄*)

下のコードを見てください。
int func(int num) { while (num >= 14) num = (num >> 3) + (num & 7); if (num >= 7) num -= 7 ; return num; }
funcという名前の関数が一つ定義されていますが、 このfunc関数、一体何をする関数か分かりますか?? ・・・といっても、これがパッと分かる人なんてそうそういないと思うので、 答えを言っちゃいますと、 実はこれ、mod 7 を求める関数です。 うっそ~~、信じらんな~い!!という人の為に、一応検証してみます。

剰余演算(mod)の関数を自作(C言語)

#include <stdio.h> #include <stdlib.h> #include <time.h> int mod7(int num) { while (num >= 14) num = (num >> 3) + (num & 7); if (num >= 7) num -= 7 ; return num; } int main(void) { int i,num; srand ((unsigned int)time(NULL)); for (i=0; i<10; i++) { num = rand(); printf("% 6d => %d - %d\n", num, num % 7, mod7(num)); } return 0; }
ランダムな整数を作成し、%演算子を使ってmod 7を行った値と、冒頭の関数の戻り値を比較するコードです。 ↓↓ 実行結果は以下のとおり ↓↓ 自作剰余演算(mod)関数の結果 はい、mod 7を求める関数が正常に動作しているのが確認できました~^^;) さてさて、この関数を眺めていると、 mod 7以外の剰余演算もできそうだな~という気がしますよね?? というわけで、改良を加えたのが以下のコードです。

剰余演算(mod)の関数を自作2(C言語)

int modX(int num, int nMod, int nBit) { while (num >= nMod * 2) num = (num >> nBit) + (num & nMod); if (num >= nMod) num -= nMod; return num; } int main(void) { int i, num, nMod, nTmp, nBit; srand((unsigned int)time(NULL)); // 剰余演算する数を設定 nMod = 15; nBit = 1; nTmp = nMod; while (nTmp >>= 1) nBit++; for (i=0; i<10; i++) { num = rand(); printf("% 6d => [% 3d] - [% 3d]\n", num, num % 15, modX(num, 15, nBit)); } return 0; }
modX関数の、引数 num には剰余演算される数、nMod には剰余演算する数を入れます (第3引数のnBitに関しては後述します)。 すると、あ~ら不思議、%演算子を使わなくても、剰余演算した結果を取得することができてしまいます! ↓↓ 実行結果はご覧のとおり(ここでは mod 15を計算してみました)↓↓ 自作剰余演算(mod)関数の結果-2 はい、正常に動作していますね^^;) さて、ではmodX関数の第3引数(nBit)についてです。 nBitには、剰余演算する数(nMod)を表示する為に必要な、最小bit数を入れます。 main関数内の
nBit = 1; nTmp = nMod; while (nTmp >>= 1) nBit++;
の部分で、ここで紹介した小技を使用し、bit数を計算しています。 ・・・では最後に、このmodX関数の最も重要なポイント(欠点ともいうw)をご紹介しておきます。 それは、剰余演算する数(nMod)に入れる事のできる数値が決まっている ということです(爆) 小さい数から順に、7, 15, 31, 63, 127, ... つまり、特定のbit数で表すことのできる最大値じゃないと、mod値を計算できません^^;) さらに、関数内の処理の大半がbit演算だから、実行速度ぐらいは速いんじゃないかな~~?? と考えて、処理時間を計測してみたんですが、%演算子を使って処理を行った方が、実行速度が速かったです^^;) ついでに、すでにお気づきの方も多いでしょうが、この関数はマイナス値が全く考慮されていません♪ というわけで、長々と書きましたが、 このネタは「多人数プロジェクトで意図的にコードの可読性を下げて嫌がらせをする」以外は、おそらく何も利点がないと思われます^^;) ここまでお付き合い下さり、 ほ ん と う に あ り が と う ご ざ い ま し た w
トリッキーコードネット の TOPへ HOTNEWS の 総合TOPへ