touched up bigint.c

This commit is contained in:
hyunghwan.chung 2019-04-09 04:40:51 +00:00
parent 904c8ded2a
commit 1131ecda11
2 changed files with 44 additions and 14 deletions

View File

@ -1701,7 +1701,6 @@ static void divide_unsigned_array (moo_t* moo, const moo_liw_t* x, moo_oow_t xs,
} }
} }
#if 1
static MOO_INLINE moo_liw_t calculate_remainder (moo_t* moo, moo_liw_t* qr, moo_liw_t* y, moo_liw_t quo, int qr_start, int stop) static MOO_INLINE moo_liw_t calculate_remainder (moo_t* moo, moo_liw_t* qr, moo_liw_t* y, moo_liw_t quo, int qr_start, int stop)
{ {
moo_lidw_t dw; moo_lidw_t dw;
@ -1899,6 +1898,15 @@ static void divide_unsigned_array3 (moo_t* moo, const moo_liw_t* x, moo_oow_t xs
return; return;
} }
#define SHARED_QQ
#if defined(SHARED_QQ)
/* as long as q is 2 words longer than x, this algorithm can store
* both quotient and remainder in q at the same time. */
qq = q;
#else
/* this part requires an extra buffer. proper error handling isn't easy
* since the return type of this function is void */
if (moo->inttostr.t.capa <= xs) if (moo->inttostr.t.capa <= xs)
{ {
moo_liw_t* t; moo_liw_t* t;
@ -1906,13 +1914,14 @@ static void divide_unsigned_array3 (moo_t* moo, const moo_liw_t* x, moo_oow_t xs
reqcapa = MOO_ALIGN_POW2(xs + 1, 32); reqcapa = MOO_ALIGN_POW2(xs + 1, 32);
t = (moo_liw_t*)moo_reallocmem(moo, moo->inttostr.t.ptr, reqcapa * MOO_SIZEOF(*t)); t = (moo_liw_t*)moo_reallocmem(moo, moo->inttostr.t.ptr, reqcapa * MOO_SIZEOF(*t));
/* TODO: TODO: TODO: ERROR HANDLING /* TODO: TODO: TODO: ERROR HANDLING
if (!t) return -1; */ if (!t) return -1; */
moo->inttostr.t.capa = xs + 1; moo->inttostr.t.capa = xs + 1;
moo->inttostr.t.ptr = t; moo->inttostr.t.ptr = t;
} }
qq = moo->inttostr.t.ptr; qq = moo->inttostr.t.ptr;
#endif
y1 = y[ys - 1]; y1 = y[ys - 1];
/*s = MOO_LIW_BITS - ((y1 == 0)? -1: get_pos_of_msb_set(y1)) - 1;*/ /*s = MOO_LIW_BITS - ((y1 == 0)? -1: get_pos_of_msb_set(y1)) - 1;*/
@ -1954,7 +1963,7 @@ static void divide_unsigned_array3 (moo_t* moo, const moo_liw_t* x, moo_oow_t xs
} }
/* multiply and subtract */ /* multiply and subtract */
for (ci = 0, i = j - ys, k = 0; k < ys; i++, k++) for (ci = 0, i = g, k = 0; k < ys; i++, k++)
{ {
dw = qhat * r[k]; dw = qhat * r[k];
di = qq[i] - ci - (dw & MOO_TYPE_MAX(moo_liw_t)); di = qq[i] - ci - (dw & MOO_TYPE_MAX(moo_liw_t));
@ -1962,13 +1971,13 @@ static void divide_unsigned_array3 (moo_t* moo, const moo_liw_t* x, moo_oow_t xs
qq[i] = (moo_liw_t)di; qq[i] = (moo_liw_t)di;
} }
MOO_ASSERT (moo, i == j); MOO_ASSERT (moo, i == j);
di = qq[j] - ci; di = qq[i] - ci;
qq[j] = di; qq[i] = di;
/* test remainder */ /* test remainder */
if (di < 0) if (di < 0)
{ {
for (ci = 0, i = j - ys, k = 0; k < ys; i++, k++) for (ci = 0, i = g, k = 0; k < ys; i++, k++)
{ {
di = (moo_lidw_t)qq[i] + r[k] + ci; di = (moo_lidw_t)qq[i] + r[k] + ci;
ci = (moo_liw_t)(di >> MOO_LIW_BITS); ci = (moo_liw_t)(di >> MOO_LIW_BITS);
@ -1977,12 +1986,23 @@ static void divide_unsigned_array3 (moo_t* moo, const moo_liw_t* x, moo_oow_t xs
MOO_ASSERT (moo, i == j); MOO_ASSERT (moo, i == j);
/*MOO_ASSERT (moo, ci == 1);*/ /*MOO_ASSERT (moo, ci == 1);*/
qq[j] += ci; qq[i] += ci;
#if defined(SHARED_QQ)
/* store the quotient word right after the remainder in q */
q[i + 1] = qhat - 1;
#else
q[g] = qhat - 1; q[g] = qhat - 1;
#endif
} }
else else
{ {
#if defined(SHARED_QQ)
/* store the quotient word right after the remainder in q */
q[i + 1] = qhat;
#else
q[g] = qhat; q[g] = qhat;
#endif
} }
} }
@ -1991,9 +2011,14 @@ static void divide_unsigned_array3 (moo_t* moo, const moo_liw_t* x, moo_oow_t xs
r[i] = (qq[i] >> s) | ((moo_lidw_t)qq[i + 1] << (MOO_LIW_BITS - s)); r[i] = (qq[i] >> s) | ((moo_lidw_t)qq[i + 1] << (MOO_LIW_BITS - s));
} }
r[i] = qq[i] >> s; r[i] = qq[i] >> s;
}
#if defined(SHARED_QQ)
for (i = 0; i <= ys; i++) { q[i] = 0; }
for (; i <= xs + 1; i++) { q[i - ys - 1] = q[i]; q[i] = 0; }
#endif #endif
}
/* ======================================================================== */ /* ======================================================================== */
static moo_oop_t add_unsigned_integers (moo_t* moo, moo_oop_t x, moo_oop_t y) static moo_oop_t add_unsigned_integers (moo_t* moo, moo_oop_t x, moo_oop_t y)
@ -2121,10 +2146,13 @@ static moo_oop_t divide_unsigned_integers (moo_t* moo, moo_oop_t x, moo_oop_t y,
MOO_ASSERT (moo, !is_less_unsigned(x, y)); MOO_ASSERT (moo, !is_less_unsigned(x, y));
moo_pushvolat (moo, &x); moo_pushvolat (moo, &x);
moo_pushvolat (moo, &y); moo_pushvolat (moo, &y);
#define USE_DIVIDE_UNSIGNED_ARRAY2 #define USE_DIVIDE_UNSIGNED_ARRAY2
/*#define USE_DIVIDE_UNSIGNED_ARRAY3*/ /*#define USE_DIVIDE_UNSIGNED_ARRAY3*/
#if defined(USE_DIVIDE_UNSIGNED_ARRAY2) || defined(USE_DIVIDE_UNSIGNED_ARRAY3) #if defined(USE_DIVIDE_UNSIGNED_ARRAY3)
qq = moo_instantiate(moo, moo->_large_positive_integer, MOO_NULL, MOO_OBJ_GET_SIZE(x) + 2);
#elif defined(USE_DIVIDE_UNSIGNED_ARRAY2)
qq = moo_instantiate(moo, moo->_large_positive_integer, MOO_NULL, MOO_OBJ_GET_SIZE(x) + 1); qq = moo_instantiate(moo, moo->_large_positive_integer, MOO_NULL, MOO_OBJ_GET_SIZE(x) + 1);
#else #else
qq = moo_instantiate(moo, moo->_large_positive_integer, MOO_NULL, MOO_OBJ_GET_SIZE(x)); qq = moo_instantiate(moo, moo->_large_positive_integer, MOO_NULL, MOO_OBJ_GET_SIZE(x));
@ -2136,7 +2164,9 @@ static moo_oop_t divide_unsigned_integers (moo_t* moo, moo_oop_t x, moo_oop_t y,
} }
moo_pushvolat (moo, &qq); moo_pushvolat (moo, &qq);
#if defined(USE_DIVIDE_UNSIGNED_ARRAY2) || defined(USE_DIVIDE_UNSIGNED_ARRAY3) #if defined(USE_DIVIDE_UNSIGNED_ARRAY3)
rr = moo_instantiate(moo, moo->_large_positive_integer, MOO_NULL, MOO_OBJ_GET_SIZE(y));
#elif defined(USE_DIVIDE_UNSIGNED_ARRAY2)
rr = moo_instantiate(moo, moo->_large_positive_integer, MOO_NULL, MOO_OBJ_GET_SIZE(y)); rr = moo_instantiate(moo, moo->_large_positive_integer, MOO_NULL, MOO_OBJ_GET_SIZE(y));
#else #else
rr = moo_instantiate(moo, moo->_large_positive_integer, MOO_NULL, MOO_OBJ_GET_SIZE(y) + 1); rr = moo_instantiate(moo, moo->_large_positive_integer, MOO_NULL, MOO_OBJ_GET_SIZE(y) + 1);
@ -2144,10 +2174,10 @@ static moo_oop_t divide_unsigned_integers (moo_t* moo, moo_oop_t x, moo_oop_t y,
moo_popvolats (moo, 3); moo_popvolats (moo, 3);
if (!rr) return MOO_NULL; if (!rr) return MOO_NULL;
#if defined(USE_DIVIDE_UNSIGNED_ARRAY2) #if defined(USE_DIVIDE_UNSIGNED_ARRAY3)
divide_unsigned_array2 (moo,
#elif defined(USE_DIVIDE_UNSIGNED_ARRAY3)
divide_unsigned_array3 (moo, divide_unsigned_array3 (moo,
#elif defined(USE_DIVIDE_UNSIGNED_ARRAY2)
divide_unsigned_array2 (moo,
#else #else
divide_unsigned_array (moo, divide_unsigned_array (moo,
#endif #endif

View File

@ -1731,7 +1731,7 @@ not_found:
if (mth) return mth; if (mth) return mth;
} }
MOO_LOG3 (moo, MOO_LOG_DEBUG, "Method '%.*js' not found in %O\n", message->len, message->ptr, receiver); MOO_LOG3 (moo, MOO_LOG_DEBUG, "Method '%.*js' not found in receiver %O\n", message->len, message->ptr, receiver);
moo_seterrbfmt (moo, MOO_ENOENT, "unable to find the method '%.*js' in %O", message->len, message->ptr, receiver); moo_seterrbfmt (moo, MOO_ENOENT, "unable to find the method '%.*js' in %O", message->len, message->ptr, receiver);
return MOO_NULL; return MOO_NULL;
} }