多倍長整数クラスの作成
ライブラリがあるだろうと少し探してみましたが、速度に最適化されたものが無さそうなので、自分で作る事にしました。
最低限の機能が実現できればよいので作りは適当です(C++に慣れてないので書き方がまずかったりもするかもです)
シフト演算のみ対応させて、かつシフト演算で指定出来る数値は31までです。
32になると "Visual Studio 2010" では少なくとも32個分ずれてくれません。
右シフトに関しては符号を見ているのではないかと推測しつつも、面倒なので後々31単位でシフト演算処理をループさせるつもりです。
#include "default.h" #include <string> using namespace BoardGames; Plate::Plate(int bit1, int bit2, int bit3) { init(); bits[2] = bit1; bits[1] = bit2; bits[0] = bit3; } Plate::Plate(const Plate &plate) { init(); bits[0] = plate.bits[0]; bits[1] = plate.bits[1]; bits[2] = plate.bits[2]; } unsigned long Plate::operator[](int num) { if (0 <= num && num <= 2) { return this->bits[num]; } return 0; } Plate Plate::operator>>(int n) { unsigned long y0, y1, y2; y0 = (bits[0] >> n) | (bits[1] << (32-n)); y1 = (bits[1] >> n) | (bits[2] << (32-n)); y2 = bits[2] >> n; return Plate(y2, y1, y0); } Plate Plate::operator<<(int n) { unsigned long y0, y1, y2; y0 = bits[0] << n; y1 = (bits[1] << n) | (bits[0] >> (32-n)); y2 = (bits[2] << n) | (bits[1] >> (32-n)); return Plate(y2, y1, y0); } string Plate::getAscii() { string ascii; unsigned long temp = 0; for (int i = 2; 0 <= i; i--) { temp = rev(bits[i]); for (int j = 0; j < 32; j++) { ascii += (char)((temp & 1) + 0x30); temp >>= 1; } } return ascii; }
■ヘッダ
namespace BoardGames { static const int PLATES_MAX_COUNT = 9; /// 数独の数字1つに対する情報 class Plate { public: void init(void) { bits[0] = 0; bits[1] = 0; bits[2] = 0; } Plate() { init(); } Plate(int bit1, int bit2, int bit3); Plate(const Plate &plate); void operator=(const Plate& plate) { bits[0] = plate.bits[0]; bits[1] = plate.bits[1]; bits[2] = plate.bits[2]; } unsigned long operator[](int num); Plate operator>>(int n); Plate operator<<(int n); string getAscii(); private: unsigned long bits[3]; inline unsigned long rev(unsigned long x) { x = (x & 0x55555555) << 1 | (x >> 1) & 0x55555555; x = (x & 0x33333333) << 2 | (x >> 2) & 0x33333333; x = (x & 0x0f0f0f0f) << 4 | (x >> 4) & 0x0f0f0f0f; x = (x << 24) | ((x & 0xff00) << 8) | ((x >> 8) & 0xff00) | (x >> 24); return x; } }; }