HOME | ドキュメント |  ブログ  |  BBS  |  瓦版  | 将棋プロジェクト |  物置小屋   

PythonからC++クラスを呼び出す 象歩ブログ ZShogi に If-Modified-Since
10 November 2007

128ビット整数クラス

C128 C++クラス
道具  

Athlon64X2 3800+ の SSE を利用して 128 ビットの論理演算が楽にできるのかと思ってたけど ビットシフトAND や SUB の使い勝手がいまいち良く無い (コツを知らないだけ?)。 しょうがないので C++ で クラス C128 を作った。 一応 128 ビットリニアな Shift-L, Shift-R, ADD, SUB と AND, OR, XOR, NOT だけ実装してみました。 乗算、除算はありません。オパピ^^

以下のようなコードで、実装的に一番遅いと思われるビットシフト演算の速度を測ったところ 0.584秒/億。

void test_shift()
{
    C128 c(1);
    for (long i = 0; i < 500000; i++) {
        for (long j = 0; j < 100; j++)
            c <<= 1;
        for (long j = 0; j < 100; j++)
            c >>= 1;
    }
}

上のプログラムの C128 を 64 ビットデータ型 (unsigned long long) を使うように修正し、 オプティマイズ無しでシフト演算してみると 0.340秒/億とあまり差が無い。 消費時間の大部分はループ処理の部分と思われるのであてにならないってことか。 (測定方法が悪いんでね;;)

話は違うけど、 単純な処理をいくつか NASM やインラインアセンブラのコードで試してみてたのですが C++ で組んでオプティマイズをかける (gcc -O3) のと大差ないようです。 特殊な事情が無ければ、今は C/C++ で十分なのだろう。


ソースコード C128.h (ヘッダ部)

// Copyright (C) 2007, Shu KONNO <owa@bg.wakwak.com>. All rights reserved.
// This program is free software licensed under the GPL 2 or above.
// Version: 1.0.0 (2007-11-10)
//
#ifndef _C128_H_
#define _C128_H_
typedef unsigned long long ULong;

class C128 {
private:
    ULong lo;
    ULong hi;
public:
    C128() : lo(0), hi(0) {}
    C128(ULong m, ULong n=0) : lo(m), hi(n) {}
    ~C128() {}
    ULong getl() const { return lo; }
    ULong geth() const { return hi; }
    C128& operator<<=(unsigned int);
    C128 operator<<(unsigned int n) const { return C128(*this) <<= n; }
    C128& operator>>=(unsigned int);
    C128 operator>>(unsigned int n) const { return C128(*this) >>= n; }
    C128& operator+=(ULong);
    C128& operator+=(C128);
    C128 operator+(ULong u) const { return C128(*this) += u; }
    C128 operator+(C128 c) const { return C128(*this) += c; }
    C128 operator+() const { return *this; }
    C128& operator-=(ULong);
    C128& operator-=(C128);
    C128 operator-(ULong u) const { return C128(*this) -= u; }
    C128 operator-(C128 c) const { return C128(*this) -= c; }
    C128 operator-() const { return C128() -= *this; }
    C128& operator&=(C128);
    C128 operator&(C128 c) const { return C128(*this) &= c; }
    C128& operator|=(C128);
    C128 operator|(C128 c) const { return C128(*this) |= c; }
    C128& operator^=(C128);
    C128 operator^(C128 c) const { return C128(*this) ^= c; }
    C128 operator~() const { return C128(~lo, ~hi); };
};
#endif // _C128_H_

ソースコード C128.cpp (処理部)

// Copyright (C) 2007, Shu KONNO <owa@bg.wakwak.com>. All rights reserved.
// This program is free software licensed under the GPL 2 or above.
// Version: 1.0.0 (2007-11-10)
//
#include "C128.h"

C128& C128::operator<<=(unsigned int n)
{
    n &= 0x07f;
    if (n >= 64) {
        hi = lo << (n - 64);
        lo = 0;
    }
    else if (n) {
        hi <<= n;
        hi |= lo >> (64 - n);
        lo <<= n;
    }
    return *this;
}

C128& C128::operator>>=(unsigned int n)
{
    n &= 0x07f;
    if (n >= 64) {
        lo = hi >> (n - 64);
        hi = 0;
    }
    else if (n) {
        lo >>= n;
        lo |= hi << (64 - n);
        hi >>= n;
    }
    return *this;
}

C128& C128::operator+=(ULong u)
{
    ULong t = lo;
    if ((lo += u) < t)
        ++hi;
    return *this;
}

C128& C128::operator+=(C128 c)
{
    ULong t = lo;
    if ((lo += c.lo) < t)
        ++hi;
    hi += c.hi;
    return *this;
}

C128& C128::operator-=(ULong u)
{
    ULong t = lo;
    if ((lo -= u) > t)
        --hi;
    return *this;
}

C128& C128::operator-=(C128 c)
{
    ULong t = lo;
    if ((lo -= c.lo) > t)
        --hi;
    hi -= c.hi;
    return *this;
}

C128& C128::operator&=(C128 c)
{
    lo &= c.lo;
    hi &= c.hi;
    return *this;
}

C128& C128::operator|=(C128 c)
{
    lo |= c.lo;
    hi |= c.hi;
    return *this;
}

C128& C128::operator^=(C128 c)
{
    lo ^= c.lo;
    hi ^= c.hi;
    return *this;
}

Comments
There is no comment.
Trackbacks

【注意】TrackBack 送信なさる場合、 あなたの記事中に参照リンク (当ブログの URL 記述) が必要です。 トラックバックスパム防止のため、御了承ください。

There is no trackback.
Post a comment











一回プレビューして投稿内容の確認をしてください。その後に投稿可能になります。