add test of window_method

update-fork
MITSUNARI Shigeo 5 years ago
parent 04157779d6
commit e0f7f5d073
  1. 34
      include/mcl/window_method.hpp
  2. 31
      test/window_method_test.cpp

@ -23,35 +23,33 @@ struct ArrayIterator {
, bitSize(bitSize) , bitSize(bitSize)
, w(w) , w(w)
, pos(0) , pos(0)
, mask((w == TbitSize ? 0 : (T(1) << w)) - 1) , mask(makeMask(w))
{ {
assert(w <= TbitSize); assert(w <= TbitSize);
} }
T makeMask(size_t w) const
{
return (w == TbitSize) ? ~T(0) : (T(1) << w) - 1;
}
bool hasNext() const { return bitSize > 0; } bool hasNext() const { return bitSize > 0; }
T getNext() T getNext()
{ {
if (w == TbitSize) { if (bitSize < w) {
bitSize -= w; w = bitSize;
return *x++; mask = makeMask(w);
} }
if (pos + w < TbitSize) { if (pos + w <= TbitSize) {
T v = (*x >> pos) & mask; T v = x[0] >> pos;
pos += w; if (pos + w < TbitSize) {
if (bitSize < w) { pos += w;
bitSize = 0; v &= mask;
} else { } else {
bitSize -= w; pos = 0;
x++;
} }
bitSize -= w;
return v; return v;
} }
if (pos + bitSize <= TbitSize) {
assert(bitSize <= w);
T v = *x >> pos;
assert((v >> bitSize) == 0);
bitSize = 0;
return v & mask;
}
assert(pos > 0);
T v = (x[0] >> pos) | (x[1] << (TbitSize - pos)); T v = (x[0] >> pos) | (x[1] << (TbitSize - pos));
v &= mask; v &= mask;
pos = (pos + w) - TbitSize; pos = (pos + w) - TbitSize;

@ -6,21 +6,24 @@
CYBOZU_TEST_AUTO(ArrayIterator) CYBOZU_TEST_AUTO(ArrayIterator)
{ {
const uint32_t in[2] = { 0x12345678, 0xabcdef89 }; const uint32_t in[] = { 0x12345678, 0xabcdef89, 0xaabbccdd };
const size_t bitSize = 64; for (size_t bitSize = 1; bitSize <= 64; bitSize++) {
for (size_t w = 1; w <= 32; w++) { for (size_t w = 1; w <= 32; w++) {
const uint32_t mask = uint32_t((uint64_t(1) << w) - 1);
mpz_class x; const uint32_t mask = uint32_t((uint64_t(1) << w) - 1);
mcl::gmp::setArray(x, in, 2); mpz_class x;
mcl::fp::ArrayIterator<uint32_t> ai(in, bitSize, w); mcl::gmp::setArray(x, in, CYBOZU_NUM_OF_ARRAY(in));
size_t n = (bitSize + w - 1) / w; x &= (mpz_class(1) << bitSize) - 1;
for (size_t j = 0; j < n; j++) { mcl::fp::ArrayIterator<uint32_t> ai(in, bitSize, w);
CYBOZU_TEST_ASSERT(ai.hasNext()); size_t n = (bitSize + w - 1) / w;
uint32_t v = ai.getNext(); for (size_t j = 0; j < n; j++) {
CYBOZU_TEST_EQUAL(x & mask, v); CYBOZU_TEST_ASSERT(ai.hasNext());
x >>= w; uint32_t v = ai.getNext();
CYBOZU_TEST_EQUAL(x & mask, v);
x >>= w;
}
CYBOZU_TEST_ASSERT(!ai.hasNext());
} }
CYBOZU_TEST_ASSERT(!ai.hasNext());
} }
} }

Loading…
Cancel
Save