add Vint:divu1, modu1

dev
MITSUNARI Shigeo 7 years ago
parent 993ed42bec
commit 585ac4f329
  1. 2
      .gitignore
  2. 42
      include/mcl/vint.hpp
  3. 4
      test/vint_test.cpp

2
.gitignore vendored

@ -1,5 +1,7 @@
CVS
java/*_wrap.cxx
lib/*.so
lib/*.a
*.class
GPATH
GRTAGS

@ -14,20 +14,20 @@
#include <iostream>
#include <mcl/util.hpp>
#ifndef MCL_VINT_UNIT_BYTE_SIZE
#define MCL_VINT_UNIT_BYTE_SIZE 4
#ifndef MCL_SIZEOF_VINT_UNIT
#define MCL_SIZEOF_VINT_UNIT 4
#endif
namespace mcl {
namespace vint {
#if MCL_VINT_UNIT_BYTE_SIZE == 8
#if MCL_SIZEOF_VINT_UNIT == 8
typedef uint64_t Unit;
#elif MCL_VINT_UNIT_BYTE_SIZE == 4
#elif MCL_SIZEOF_VINT_UNIT == 4
typedef uint32_t Unit;
#else
#error "define MCL_VINT_UNIT_BYTE_SIZE"
#error "define MCL_SIZEOF_VINT_UNIT"
#endif
inline uint64_t make64(uint32_t H, uint32_t L)
@ -47,7 +47,7 @@ inline void split64(uint32_t *H, uint32_t *L, uint64_t x)
*/
static inline Unit mulUnit(Unit *H, Unit a, Unit b)
{
#if MCL_VINT_UNIT_BYTE_SIZE == 4
#if MCL_SIZEOF_VINT_UNIT == 4
uint64_t t = uint64_t(a) * b;
uint32_t L;
split64(H, &L, t);
@ -71,7 +71,7 @@ static inline Unit mulUnit(Unit *H, Unit a, Unit b)
*/
static Unit divUnit(Unit *r, Unit H, Unit L, Unit y)
{
#if MCL_VINT_UNIT_BYTE_SIZE == 4
#if MCL_SIZEOF_VINT_UNIT == 4
uint64_t t = make64(H, L);
uint32_t q = uint32_t(t / y);
*r = Unit(t % y);
@ -117,7 +117,7 @@ template<class T>
inline void decStr2Int(T& x, const std::string& s)
{
const size_t width = 9;
const uint32_t d = (uint32_t)std::pow(10.0, 9);
const typename T::Unit d = (uint32_t)std::pow(10.0, 9);
size_t size = s.size();
size_t q = size / width;
size_t r = size % width;
@ -126,7 +126,7 @@ inline void decStr2Int(T& x, const std::string& s)
split s and compute x
eg. 123456789012345678901234 => 123456, 789012345, 678901234
*/
uint32_t v;
typename T::Unit v;
x = 0;
if (r) {
v = cybozu::atoi(p, r);
@ -449,7 +449,7 @@ static inline double GetApp(const T *x, size_t xn, bool up)
union di di;
di.f = (double)H;
unsigned int len = int(di.i >> 52) - 1023 + 1;
#if MCL_VINT_UNIT_BYTE_SIZE == 4
#if MCL_SIZEOF_VINT_UNIT == 4
uint32_t M = x[xn - 2];
if (len >= 21) {
di.i |= M >> (len - 21);
@ -1313,6 +1313,16 @@ public:
z.isNeg_ = x.isNeg_;
z.trim(zn);
}
static void divu1(VintT& q, const VintT& x, Unit y)
{
udivModu1(&q, x, y);
}
static void modu1(VintT& r, const VintT& x, Unit y)
{
bool xNeg = x.isNeg_;
r = divModu1(0, x, y);
r.isNeg_ = xNeg;
}
static void adds1(VintT& z, const VintT& x, int y)
{
if (y == invalidVar) throw cybozu::Exception("VintT:adds1:bad y");
@ -1743,6 +1753,12 @@ public:
VintT& operator*=(int rhs) { muls1(*this, *this, rhs); return *this; }
VintT& operator/=(int rhs) { divs1(*this, *this, rhs); return *this; }
VintT& operator%=(int rhs) { mods1(*this, *this, rhs); return *this; }
VintT& operator+=(Unit rhs) { addu1(*this, *this, rhs); return *this; }
VintT& operator-=(Unit rhs) { subu1(*this, *this, rhs); return *this; }
VintT& operator*=(Unit rhs) { mulu1(*this, *this, rhs); return *this; }
VintT& operator/=(Unit rhs) { divu1(*this, *this, rhs); return *this; }
VintT& operator%=(Unit rhs) { modu1(*this, *this, rhs); return *this; }
VintT& operator&=(Unit rhs) { andBitu1(*this, *this, rhs); return *this; }
VintT& operator|=(Unit rhs) { orBitu1(*this, *this, rhs); return *this; }
@ -1759,6 +1775,12 @@ public:
friend VintT operator*(const VintT& a, int b) { VintT c; muls1(c, a, b); return c; }
friend VintT operator/(const VintT& a, int b) { VintT c; divs1(c, a, b); return c; }
friend VintT operator%(const VintT& a, int b) { VintT c; mods1(c, a, b); return c; }
friend VintT operator+(const VintT& a, Unit b) { VintT c; addu1(c, a, b); return c; }
friend VintT operator-(const VintT& a, Unit b) { VintT c; subu1(c, a, b); return c; }
friend VintT operator*(const VintT& a, Unit b) { VintT c; mulu1(c, a, b); return c; }
friend VintT operator/(const VintT& a, Unit b) { VintT c; divu1(c, a, b); return c; }
friend VintT operator%(const VintT& a, Unit b) { VintT c; modu1(c, a, b); return c; }
friend VintT operator&(const VintT& a, Unit b) { VintT c; andBitu1(c, a, b); return c; }
friend VintT operator|(const VintT& a, Unit b) { VintT c; orBitu1(c, a, b); return c; }

@ -190,7 +190,7 @@ CYBOZU_TEST_AUTO(mul1)
{
static const struct {
V a;
unsigned int b;
int b;
V c;
} tbl[] = {
{
@ -226,7 +226,7 @@ CYBOZU_TEST_AUTO(mul1)
};
for (size_t i = 0; i < CYBOZU_NUM_OF_ARRAY(tbl); i++) {
Vint x, z, t;
unsigned int y;
int y;
x.setArray(tbl[i].a.p, tbl[i].a.n);
y = tbl[i].b;
z.setArray(tbl[i].c.p, tbl[i].c.n);

Loading…
Cancel
Save