added some code for bigint division
This commit is contained in:
parent
48efc4dbc8
commit
a32e1903bf
@ -279,6 +279,15 @@ PROCESS TESTING
|
|||||||
(7 \\ -3) dump.
|
(7 \\ -3) dump.
|
||||||
(7 // -3) dump.
|
(7 // -3) dump.
|
||||||
|
|
||||||
|
##(777777777777777777777777777777777777777777777777777777777777777777777 rem: -8127348917239812731289371289731298) dump.
|
||||||
|
##(777777777777777777777777777777777777777777777777777777777777777777777 quo: -8127348917239812731289371289731298) dump.
|
||||||
|
|
||||||
|
(-270000000000000000000000000000000000000000000000000000000000000000000 rem: 50000000000000000000000000000000000000000000000000000000000000000000) dump.
|
||||||
|
(-270000000000000000000000000000000000000000000000000000000000000000000 quo: 50000000000000000000000000000000000000000000000000000000000000000000) dump.
|
||||||
|
(-270000000000000000000000000000000000000000000000000000000000000000000 \\ 50000000000000000000000000000000000000000000000000000000000000000000) dump.
|
||||||
|
(-270000000000000000000000000000000000000000000000000000000000000000000 // 50000000000000000000000000000000000000000000000000000000000000000000) dump.
|
||||||
|
|
||||||
|
|
||||||
"
|
"
|
||||||
FFI isNil dump.
|
FFI isNil dump.
|
||||||
FFI notNil dump.
|
FFI notNil dump.
|
||||||
|
@ -283,6 +283,19 @@ static STIX_INLINE stix_oop_t clone_bigint_negated (stix_t* stix, stix_oop_t oop
|
|||||||
return z;
|
return z;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static STIX_INLINE stix_oow_t count_effective (stix_liw_t* x, stix_oow_t xs)
|
||||||
|
{
|
||||||
|
stix_oow_t i;
|
||||||
|
|
||||||
|
for (i = xs; i > 1; )
|
||||||
|
{
|
||||||
|
--i;
|
||||||
|
if (x[i] != 0) return i + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
static STIX_INLINE stix_oow_t count_effective_digits (stix_oop_t oop)
|
static STIX_INLINE stix_oow_t count_effective_digits (stix_oop_t oop)
|
||||||
{
|
{
|
||||||
stix_oow_t i;
|
stix_oow_t i;
|
||||||
@ -637,7 +650,7 @@ static void divide_unsigned_array (
|
|||||||
const stix_liw_t* y, stix_oow_t ys,
|
const stix_liw_t* y, stix_oow_t ys,
|
||||||
stix_liw_t* q, stix_liw_t* r)
|
stix_liw_t* q, stix_liw_t* r)
|
||||||
{
|
{
|
||||||
/* TODO: this function needs to be rewritten for performance improvement. */
|
/* TODO: this function needs to be rewritten for performance improvement. */
|
||||||
|
|
||||||
/* Perform binary long division.
|
/* Perform binary long division.
|
||||||
* http://en.wikipedia.org/wiki/Division_algorithm
|
* http://en.wikipedia.org/wiki/Division_algorithm
|
||||||
@ -654,16 +667,32 @@ static void divide_unsigned_array (
|
|||||||
* end
|
* end
|
||||||
*/
|
*/
|
||||||
|
|
||||||
stix_liw_t* d;
|
stix_oow_t rs, i , j;
|
||||||
stix_oow_t ds;
|
|
||||||
|
|
||||||
/* TODO: */
|
STIX_ASSERT (xs >= ys);
|
||||||
while (!is_less_unsigned_array (d, ds, y, ys)) /* while (y <= d) */
|
STIX_MEMSET (q, 0, STIX_SIZEOF(*q) * xs);
|
||||||
|
STIX_MEMSET (r, 0, STIX_SIZEOF(*q) * xs);
|
||||||
|
|
||||||
|
/*rs = 1; */
|
||||||
|
for (i = xs; i > 0; )
|
||||||
{
|
{
|
||||||
|
--i;
|
||||||
|
for (j = STIX_SIZEOF(stix_liw_t) * 8; j > 0;)
|
||||||
|
{
|
||||||
|
--j;
|
||||||
|
|
||||||
|
lshift_unsigned_array (r, xs, 1);
|
||||||
|
STIX_SETBITS (stix_liw_t, r[0], 0, 1, STIX_GETBITS(stix_liw_t, x[i], j, 1));
|
||||||
|
|
||||||
|
rs = count_effective (r, xs);
|
||||||
|
if (!is_less_unsigned_array (r, rs, y, ys))
|
||||||
|
{
|
||||||
|
subtract_unsigned_array (r, rs, y, ys, r);
|
||||||
|
STIX_SETBITS (stix_liw_t, q[i], j, 1, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*if (xs > rs && r[rs] > 0) rs++;*/
|
||||||
}
|
}
|
||||||
|
|
||||||
STIX_MEMCPY (r, d, ds);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static stix_oop_t add_unsigned_integers (stix_t* stix, stix_oop_t x, stix_oop_t y)
|
static stix_oop_t add_unsigned_integers (stix_t* stix, stix_oop_t x, stix_oop_t y)
|
||||||
@ -700,7 +729,7 @@ static stix_oop_t subtract_unsigned_integers (stix_t* stix, stix_oop_t x, stix_o
|
|||||||
{
|
{
|
||||||
stix_oop_t z;
|
stix_oop_t z;
|
||||||
|
|
||||||
STIX_ASSERT (!is_less(stix, x, y));
|
STIX_ASSERT (!is_less_unsigned(x, y));
|
||||||
|
|
||||||
stix_pushtmp (stix, &x);
|
stix_pushtmp (stix, &x);
|
||||||
stix_pushtmp (stix, &y);
|
stix_pushtmp (stix, &y);
|
||||||
@ -730,6 +759,28 @@ static stix_oop_t multiply_unsigned_integers (stix_t* stix, stix_oop_t x, stix_o
|
|||||||
return z;
|
return z;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static stix_oop_t divide_unsigned_integers (stix_t* stix, stix_oop_t x, stix_oop_t y, stix_oop_t* r)
|
||||||
|
{
|
||||||
|
stix_oop_t qq, rr;
|
||||||
|
|
||||||
|
/* the caller must ensure that x >= y */
|
||||||
|
STIX_ASSERT (!is_less_unsigned (x, y));
|
||||||
|
stix_pushtmp (stix, &x);
|
||||||
|
stix_pushtmp (stix, &y);
|
||||||
|
qq = stix_instantiate (stix, stix->_large_positive_integer, STIX_NULL, STIX_OBJ_GET_SIZE(x));
|
||||||
|
stix_pushtmp (stix, &qq);
|
||||||
|
rr = stix_instantiate (stix, stix->_large_positive_integer, STIX_NULL, STIX_OBJ_GET_SIZE(x));
|
||||||
|
stix_poptmps (stix, 3);
|
||||||
|
|
||||||
|
divide_unsigned_array (
|
||||||
|
((stix_oop_liword_t)x)->slot, STIX_OBJ_GET_SIZE(x),
|
||||||
|
((stix_oop_liword_t)y)->slot, STIX_OBJ_GET_SIZE(y),
|
||||||
|
((stix_oop_liword_t)qq)->slot, ((stix_oop_liword_t)rr)->slot);
|
||||||
|
|
||||||
|
if (r) *r = rr;
|
||||||
|
return qq;
|
||||||
|
}
|
||||||
|
|
||||||
stix_oop_t stix_addints (stix_t* stix, stix_oop_t x, stix_oop_t y)
|
stix_oop_t stix_addints (stix_t* stix, stix_oop_t x, stix_oop_t y)
|
||||||
{
|
{
|
||||||
stix_oop_t z;
|
stix_oop_t z;
|
||||||
@ -789,14 +840,33 @@ stix_oop_t stix_addints (stix_t* stix, stix_oop_t x, stix_oop_t y)
|
|||||||
if (STIX_OBJ_GET_CLASS(x) == stix->_large_negative_integer)
|
if (STIX_OBJ_GET_CLASS(x) == stix->_large_negative_integer)
|
||||||
{
|
{
|
||||||
/* x is negative, y is positive */
|
/* x is negative, y is positive */
|
||||||
z = stix_subints (stix, y, x);
|
if (is_less_unsigned (x, y))
|
||||||
|
{
|
||||||
|
z = subtract_unsigned_integers (stix, y, x);
|
||||||
|
if (!z) return STIX_NULL;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
z = subtract_unsigned_integers (stix, x, y);
|
||||||
|
if (!z) return STIX_NULL;
|
||||||
|
STIX_OBJ_SET_CLASS(z, stix->_large_negative_integer);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* x is positive, y is negative */
|
/* x is positive, y is negative */
|
||||||
z = stix_subints (stix, x, y);
|
if (is_less_unsigned (x, y))
|
||||||
}
|
{
|
||||||
|
z = subtract_unsigned_integers (stix, y, x);
|
||||||
if (!z) return STIX_NULL;
|
if (!z) return STIX_NULL;
|
||||||
|
STIX_OBJ_SET_CLASS(z, stix->_large_negative_integer);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
z = subtract_unsigned_integers (stix, x, y);
|
||||||
|
if (!z) return STIX_NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -1036,7 +1106,8 @@ oops_einval:
|
|||||||
|
|
||||||
stix_oop_t stix_divints (stix_t* stix, stix_oop_t x, stix_oop_t y, int modulo, stix_oop_t* rem)
|
stix_oop_t stix_divints (stix_t* stix, stix_oop_t x, stix_oop_t y, int modulo, stix_oop_t* rem)
|
||||||
{
|
{
|
||||||
stix_oop_t t;
|
stix_oop_t z;
|
||||||
|
int x_neg, y_neg;
|
||||||
|
|
||||||
if (STIX_OOP_IS_SMOOI(x) && STIX_OOP_IS_SMOOI(y))
|
if (STIX_OOP_IS_SMOOI(x) && STIX_OOP_IS_SMOOI(y))
|
||||||
{
|
{
|
||||||
@ -1127,43 +1198,145 @@ stix_oop_t stix_divints (stix_t* stix, stix_oop_t x, stix_oop_t y, int modulo, s
|
|||||||
}
|
}
|
||||||
else if (STIX_OOP_IS_SMOOI(x))
|
else if (STIX_OOP_IS_SMOOI(x))
|
||||||
{
|
{
|
||||||
if (STIX_OOP_TO_SMOOI(x) == 0)
|
stix_ooi_t v;
|
||||||
|
|
||||||
|
v = STIX_OOP_TO_SMOOI(x);
|
||||||
|
if (v == 0)
|
||||||
{
|
{
|
||||||
if (rem)
|
if (rem)
|
||||||
{
|
{
|
||||||
t = clone_bigint (stix, y, STIX_OBJ_GET_SIZE(y));
|
z = clone_bigint (stix, y, STIX_OBJ_GET_SIZE(y));
|
||||||
if (!t) return STIX_NULL;
|
if (!z) return STIX_NULL;
|
||||||
*rem = t;
|
*rem = z;
|
||||||
}
|
}
|
||||||
return STIX_SMOOI_TO_OOP(0);
|
return STIX_SMOOI_TO_OOP(0);
|
||||||
}
|
}
|
||||||
/* TODO: convert x to bigint */
|
|
||||||
|
stix_pushtmp (stix, &y);
|
||||||
|
x = make_bigint_with_ooi (stix, v);
|
||||||
|
stix_poptmp (stix);
|
||||||
}
|
}
|
||||||
else if (STIX_OOP_IS_SMOOI(y))
|
else if (STIX_OOP_IS_SMOOI(y))
|
||||||
{
|
{
|
||||||
switch (STIX_OOP_TO_SMOOI(y))
|
stix_ooi_t v;
|
||||||
|
|
||||||
|
v = STIX_OOP_TO_SMOOI(y);
|
||||||
|
switch (v)
|
||||||
{
|
{
|
||||||
case 0:
|
case 0:
|
||||||
stix->errnum = STIX_EDIVBY0;
|
stix->errnum = STIX_EDIVBY0;
|
||||||
return STIX_NULL;
|
return STIX_NULL;
|
||||||
|
|
||||||
case 1:
|
case 1:
|
||||||
t = clone_bigint (stix, x, STIX_OBJ_GET_SIZE(x));
|
z = clone_bigint (stix, x, STIX_OBJ_GET_SIZE(x));
|
||||||
if (!t) return STIX_NULL;
|
if (!z) return STIX_NULL;
|
||||||
if (rem) *rem = STIX_SMOOI_TO_OOP(0);
|
if (rem) *rem = STIX_SMOOI_TO_OOP(0);
|
||||||
return t;
|
return z;
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
case 2:
|
||||||
|
DO SHIFTING.
|
||||||
|
* if v is powerof2, do shifting???
|
||||||
|
*/
|
||||||
case -1:
|
case -1:
|
||||||
t = clone_bigint_negated (stix, x, STIX_OBJ_GET_SIZE(x));
|
z = clone_bigint_negated (stix, x, STIX_OBJ_GET_SIZE(x));
|
||||||
if (!t) return STIX_NULL;
|
if (!z) return STIX_NULL;
|
||||||
if (rem) *rem = STIX_SMOOI_TO_OOP(0);
|
if (rem) *rem = STIX_SMOOI_TO_OOP(0);
|
||||||
return t;
|
return z;
|
||||||
}
|
|
||||||
/* TODO: convert y to bigint */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* TODO: do bigint division. */
|
stix_pushtmp (stix, &x);
|
||||||
return STIX_NULL;
|
y = make_bigint_with_ooi (stix, v);
|
||||||
|
stix_poptmp (stix);
|
||||||
|
}
|
||||||
|
|
||||||
|
x_neg = STIX_OBJ_GET_CLASS(x) == stix->_large_negative_integer;
|
||||||
|
y_neg = STIX_OBJ_GET_CLASS(y) == stix->_large_negative_integer;
|
||||||
|
|
||||||
|
stix_pushtmp (stix, &x);
|
||||||
|
stix_pushtmp (stix, &y);
|
||||||
|
z = divide_unsigned_integers (stix, x, y, rem);
|
||||||
|
stix_poptmps (stix, 2);
|
||||||
|
if (!z) return STIX_NULL;
|
||||||
|
if (x_neg != y_neg)
|
||||||
|
{
|
||||||
|
STIX_OBJ_SET_CLASS(z, stix->_large_negative_integer);
|
||||||
|
}
|
||||||
|
|
||||||
|
{ int i;
|
||||||
|
printf ("QUO=>");
|
||||||
|
for (i = STIX_OBJ_GET_SIZE(z); i > 0;)
|
||||||
|
{
|
||||||
|
printf ("%0*lX ", (int)(STIX_SIZEOF(stix_liw_t) * 2), (unsigned long)((stix_oop_liword_t)z)->slot[--i]);
|
||||||
|
}
|
||||||
|
printf ("\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* TODO: handle modulo... */
|
||||||
|
if (rem)
|
||||||
|
{
|
||||||
|
stix_pushtmp (stix, &z);
|
||||||
|
*rem = normalize_bigint (stix, *rem);
|
||||||
|
stix_poptmp (stix);
|
||||||
|
if (!*rem) return STIX_NULL;
|
||||||
|
|
||||||
|
if (x_neg)
|
||||||
|
{
|
||||||
|
STIX_OBJ_SET_CLASS(*rem, stix->_large_negative_integer);
|
||||||
|
if (modulo)
|
||||||
|
{
|
||||||
|
{ int i;
|
||||||
|
printf ("REM=>");
|
||||||
|
for (i = STIX_OBJ_GET_SIZE(*rem); i > 0;)
|
||||||
|
{
|
||||||
|
printf ("%0*lX ", (int)(STIX_SIZEOF(stix_liw_t) * 2), (unsigned long)((stix_oop_liword_t)*rem)->slot[--i]);
|
||||||
|
}
|
||||||
|
printf ("\n");
|
||||||
|
}
|
||||||
|
stix_pushtmp (stix, &z);
|
||||||
|
stix_pushtmp (stix, &y);
|
||||||
|
*rem = stix_addints (stix, *rem, y);
|
||||||
|
stix_poptmps (stix, 2);
|
||||||
|
if (!*rem) return STIX_NULL;
|
||||||
|
|
||||||
|
{ int i;
|
||||||
|
printf ("REM=>");
|
||||||
|
for (i = STIX_OBJ_GET_SIZE(*rem); i > 0;)
|
||||||
|
{
|
||||||
|
printf ("%0*lX ", (int)(STIX_SIZEOF(stix_liw_t) * 2), (unsigned long)((stix_oop_liword_t)*rem)->slot[--i]);
|
||||||
|
}
|
||||||
|
printf ("\n");
|
||||||
|
}
|
||||||
|
stix_pushtmp (stix, rem);
|
||||||
|
z = normalize_bigint (stix, z);
|
||||||
|
stix_poptmp (stix);
|
||||||
|
if (!z) return STIX_NULL;
|
||||||
|
|
||||||
|
stix_pushtmp (stix, rem);
|
||||||
|
z = stix_subints (stix, z, STIX_SMOOI_TO_OOP(1));
|
||||||
|
stix_poptmp (stix);
|
||||||
|
return z;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
{ int i;
|
||||||
|
printf ("REM=>");
|
||||||
|
for (i = STIX_OBJ_GET_SIZE(*rem); i > 0;)
|
||||||
|
{
|
||||||
|
printf ("%0*lX ", (int)(STIX_SIZEOF(stix_liw_t) * 2), (unsigned long)((stix_oop_liword_t)*rem)->slot[--i]);
|
||||||
|
}
|
||||||
|
printf ("\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
else if (modulo && x_neg)
|
||||||
|
{
|
||||||
|
z = normalize_bigint (stix, z);
|
||||||
|
return stix_subints (stix, z, STIX_SMOOI_TO_OOP(1));
|
||||||
|
}
|
||||||
|
|
||||||
|
return normalize_bigint (stix, z);
|
||||||
}
|
}
|
||||||
|
|
||||||
static stix_uint8_t ooch_val_tab[] =
|
static stix_uint8_t ooch_val_tab[] =
|
||||||
|
Loading…
Reference in New Issue
Block a user