«前の日記(2006.08.17 / Thursday) 最新 次の日記(2006.08.19 / Saturday)» 編集

Hena Hena Nikki

2003|05|06|07|08|09|10|11|12|
2004|01|02|03|04|05|06|07|08|09|10|11|12|
2005|01|02|03|04|05|06|07|08|09|10|11|12|
2006|01|02|03|04|05|06|07|08|09|10|11|12|
2007|01|02|03|04|05|06|07|08|09|10|11|12|
2008|01|02|03|04|05|06|07|08|09|10|11|12|
2009|01|02|03|04|05|06|07|08|09|10|11|12|
2010|01|02|03|04|05|06|07|08|09|10|11|12|
2011|01|02|03|04|05|06|07|08|10|11|12|
2012|01|02|03|04|05|06|07|08|10|12|
2013|01|02|04|06|

2006.08.18 / Friday [長年日記]

* [computer/update] Ruby ver.1.8.5 preview4

object-oriented programming を意識して作られた interpreted scripting language。 所謂人柱版。

* [computer/update] PHP ver.5.1.5

動的な web page 作成に向いているスクリプト言語。

* [computer/update] PHP ver.4.4.4

動的な web page 作成に向いているスクリプト言語。

* [computer/update] QuickTime Alternative ver.1.75

QuickTime 形式のメディア・ファイルを再生するライブラリなどの詰合せ for Windows。

* [computer/update] Real Alternative ver.1.50

RealMedia 形式のメディア・ファイルを再生するライブラリなどの詰合せ for Windows。 約 2 ヶ月ぶりの version up。

* [computer] SDL 1.2.11 を Mac OS X 10.4 にインストールする

特別なことは無さそう。 もちろん CFLAGS はお好みで。

$ wget -c http://www.libsdl.org/release/SDL-1.2.11.tar.gz
$ zcat SDL-1.2.11.tar.gz | tar xvf -
$ cd SDL-1.2.11/
$ ./configure
$ make && make test
$ sudo make install

ついでに SDL_mixer 1.2.7 も入れる。 事前に libogg, libvorbis (とずっと更新されてない SMPEG) を入れておくと、勝手に使ってくれるみたいだ。

$ wget -c http://www.libsdl.org/projects/SDL_mixer/release/SDL_mixer-1.2.7.tar.gz
$ zcat SDL_mixer-1.2.7.tar.gz | tar xvf -
$ cd SDL_mixer-1.2.7/
$ ./configure
$ make
$ sudo make install

この状態で wxWidgets を入れたかったわけですよ。 :-)

* [computer/update] Lancer 20060818

Ogg Vorbis 系ツールやライブラリの高速化を狙ったもの。

* [myself] お盆休みを振り返って

外出して遊んでばかりいたけど、いちおう移動時の一部は本を読んで勉強した。 本を読むこと自体は別に良いと思うんだけど、 解らない箇所があると理解できるまで気になってしかたなく、 遊びに集中し切れずちょっと損した感じ。 研究開発関係も含め、仕事やその他の勉強、 そして遊びも集中して手抜きせずにいきたいのに。

奈良県南部って面白い。 記紀の世界の面影がそこら中に残っていて、 ちょっとした資料片手に歩くだけでもとても楽しめる。 秋になって涼しくなったら、 折り畳み自転車を持っていって、じっくり古墳巡りをしたい。

* [computer] Re: 頻繁に素数の判定を行いたい

というわけで、更にちょっとだけ prime.hpp を書き直した。 ついでに自分の実装の効果を確認できる様な main.cpp を作ってみた。

/**
 * @file    main.cpp
 * @brief   PrimeChecker クラスのテスト・コマンド
 */
// ヘッダ・ファイル #include <iostream> #include <cmath> #include <cctype> #include <cstdlib> #include <ctime> #ifndef USING_INTERNAL_PRIME_CHECKER #include "prime.hpp" #endif // USING_INTERNAL_PRIME_CHECKER
// 名前の解決 using namespace std;
/** * @brief 使用方法の表示 * @param command [in] コマンド名 */ void PrintUsage(const char* const command) { cerr << "Usage: " << command << " [integer (>1)]" << endl; }
/** * @brief 素数か否かのチェック * @param target [in] チェック対象の数 * @return * - true: 引数 target は素数 * - false: 引数 target は合成数か、1 以下の数 * @note UINT_TYPE には (unsigned 系の) 整数型を適用すること。 */ template<typename UINT_TYPE> inline bool IsPrime(const UINT_TYPE target) { if (target % 2 == 0) return target == 2; if (target < 2) return false; const UINT_TYPE sqrt_target = sqrt(target); for (UINT_TYPE i(3); i <= sqrt_target; i += 2) { if (target % i == 0) return false; } return true; }
/** * @brief PrimeChecker クラスのテスト・コマンド */ int main(int arg_count, char** arg_strings) { // 引数のチェック unsigned int loop(10000000); if (arg_count > 2) { PrintUsage(arg_strings[0]); return -1; } else if (arg_count == 2) { const char* arg_string = arg_strings[1]; while (*arg_string != '\0') { if (isdigit(*arg_string) == 0) { PrintUsage(arg_strings[0]); return -2; } ++arg_string; } loop = atoi(arg_strings[1]); if (loop < 1) { PrintUsage(arg_strings[0]); return -3; } }
// 計算開始の出力 clog << "Calculating..." << endl;
#ifndef USING_INTERNAL_PRIME_CHECKER // 素数チェッカーの準備 PrimeChecker<unsigned int> pchecker; #endif // USING_INTERNAL_PRIME_CHECKER
// 素数のチェック srand(static_cast<unsigned int>(time(0))); size_t interval_results(0); size_t total_results(0); unsigned int i(0); unsigned int maximal_prime(0); unsigned int largest_prime(0); unsigned int number; unsigned long long int total_number(0); bool result; do { ++i; number = rand(); total_number += number; #ifndef USING_INTERNAL_PRIME_CHECKER result = pchecker.checkPrime(number); #else // USING_INTERNAL_PRIME_CHECKER result = IsPrime(number); #endif // USING_INTERNAL_PRIME_CHECKER if (result) { ++interval_results; if (maximal_prime < number) { maximal_prime = number; } } if (i % 1000000 == 0) { clog << "> " << interval_results << " primes found... (MP: " << maximal_prime << ')' << endl; total_results += interval_results; interval_results = 0; if (largest_prime < maximal_prime) { largest_prime = maximal_prime; } maximal_prime = 0; } } while (i < loop); total_results += interval_results; if (largest_prime < maximal_prime) { largest_prime = maximal_prime; }
// 結果の出力 clog << total_results << " primes exist in " << loop << " numbers.\n" << "\t- " << total_number / loop << ": Average of numbers."; if (total_results > 0) { clog << "\n\t- " << largest_prime <<": Largest prime in numbers."; } clog << endl;
return 0; }

IsPrime() の実装は他のにしたいところだけど、 とりあえず実行結果を…。

$ g++ -Wall -O3 -DUSING_INTERNAL_PRIME_CHECKER main.cpp -o primes
$ time ./primes 50000000
[...]
2447754 primes exist in 50000000 numbers.
        - 1073897874: Average of numbers.
        - 2147483179: Largest prime in numbers.
666.775u 0.868s 11:09.15 99.7%  0+0k 0+0io 0pf+0w
$ g++ -Wall -O3 main.cpp -o primes
$ time ./primes 50000000
[...]
2447219 primes exist in 50000000 numbers.
        - 1073695078: Average of numbers.
        - 2147483549: Largest prime in numbers.
205.007u 0.214s 3:25.34 99.9%   0+0k 0+2io 0pf+0w

まあ…、この程度は当然の結果か。

アホなミスを複数見つけたので、こそこそ修正。 駄目だなぁ…。

当たり前だけど、このコマンドの場合、 PrimeChecker::checkPrime() は以下の形にした方が速い。 というわけで、0 からの指定範囲の素数の個数を算出するテスト・コマンドは破棄。

    /**
     * @brief   素数か否かのチェック
     * @param   target [in] チェック対象の数
     * @return
     *          - true: 引数 target は素数
     *          - false: 引数 target は合成数か、1 以下の数
     */
    inline bool checkPrime(const UINT_TYPE target)
        {
            if (target % 2 == 0) return target == 2;
            if (target < 1) return false;
            SIZE_TYPE i(0);
            const UINT_TYPE sqrt_target = std::sqrt(target);
            if (sqrt_target < primes_.back()) {
                while (primes_[i] <= sqrt_target) {
                    if (target % primes_[i] == 0) return false;
                    ++i;
                }
                return true;
            }
            SIZE_TYPE size = primes_.size();
            while (i < size) {
                if (target % primes_[i] == 0) return false;
                ++i;
            }
            UINT_TYPE divisor(next_check_);
            while (divisor <= sqrt_target) {
                for (i = 0; i < size; ++i) {
                    if (divisor % primes_[i] == 0) break;
                }
                if (i >= size) {
                    primes_.push_back(divisor);
                    if (target % divisor == 0) {
                        next_check_ = divisor + 2;
                        return false;
                    }
                    ++size;
                }
                divisor += 2;
            }
            next_check_ = divisor;
            return true;
        }
$ g++ -Wall -O3 main.cpp -o primes
$ time ./primes 50000000
[...]
2449294 primes exist in 50000000 numbers.
        - 1073763094: Average of numbers.
        - 2147483171: Largest prime in numbers.
155.911u 0.194s 2:36.25 99.9%   0+0k 0+2io 0pf+0w

以上、大量のランダムな数を対象にした素数判定クラスを、 普通の工夫をして実装してみました。 PrimeChecker::checkPrime() 中の素数テーブル拡大の処理部分は、 本当はもっとしっかり書くべきなんですけど、 意外に効果がなかったので気にしない方向で。


  • この日記には本日 名の方が訪問してくださっているようです。 また、昨日は 名の方が訪問してくださったようです。
  • この日記の更新情報の取得には antenna.lirs を利用するのがおすすめです。