added the missing zero check in stix_divint()

This commit is contained in:
hyunghwan.chung 2015-11-30 15:17:41 +00:00
parent a32e1903bf
commit addd201beb
3 changed files with 104 additions and 95 deletions

View File

@ -288,6 +288,16 @@ PROCESS TESTING
(-270000000000000000000000000000000000000000000000000000000000000000000 // 50000000000000000000000000000000000000000000000000000000000000000000) dump.
##(-270000000000000000000000000000000000000000000000000000000000000000000 rem: 5) dump.
##(-270000000000000000000000000000000000000000000000000000000000000000000 quo: 5) dump.
##(-270000000000000000000000000000000000000000000000000000000000000000000 \\ 5) dump.
##(-270000000000000000000000000000000000000000000000000000000000000000000 // 5) dump.
##(-270 rem: 5) dump.
##(-270 quo: 5) dump.
##(-270 \\ 5) dump.
##(-270 // 5) dump.
"
FFI isNil dump.
FFI notNil dump.

View File

@ -777,7 +777,7 @@ static stix_oop_t divide_unsigned_integers (stix_t* stix, stix_oop_t x, stix_oop
((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;
*r = rr;
return qq;
}
@ -1106,7 +1106,7 @@ 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 z;
stix_oop_t z, r;
int x_neg, y_neg;
if (STIX_OOP_IS_SMOOI(x) && STIX_OOP_IS_SMOOI(y))
@ -1131,7 +1131,7 @@ stix_oop_t stix_divints (stix_t* stix, stix_oop_t x, stix_oop_t y, int modulo, s
* mathematical relationship (all variables are integers):
* a/b = q with remainder r
* such that
* b*q + r = a and 0 <= r < b (assuming a and b are >= 0).
* b*q + r = a and 0 <= r < b (assuming- a and b are >= 0).
*
* If you want the relationship to extend for negative a
* (keeping b positive), you have two choices: if you truncate q
@ -1144,6 +1144,8 @@ stix_oop_t stix_divints (stix_t* stix, stix_oop_t x, stix_oop_t y, int modulo, s
STIX_ASSERT (STIX_IN_SMOOI_RANGE(q));
r = xv - yv * q; /* xv % yv; */
if (r)
{
if (modulo)
{
/* modulo */
@ -1187,6 +1189,7 @@ stix_oop_t stix_divints (stix_t* stix, stix_oop_t x, stix_oop_t y, int modulo, s
STIX_ASSERT (xv && ((xv ^ r) >= 0));
}
}
}
if (rem)
{
@ -1256,86 +1259,64 @@ DO SHIFTING.
stix_pushtmp (stix, &x);
stix_pushtmp (stix, &y);
z = divide_unsigned_integers (stix, x, y, rem);
z = divide_unsigned_integers (stix, x, y, &r);
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 != y_neg) STIX_OBJ_SET_CLASS(z, stix->_large_negative_integer);
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");
}
/* the class on r must be set before normalize_bigint()
* because it can turn it to a small integer */
STIX_OBJ_SET_CLASS(r, stix->_large_negative_integer);
stix_pushtmp (stix, &z);
stix_pushtmp (stix, &y);
*rem = stix_addints (stix, *rem, y);
r = normalize_bigint (stix, r);
stix_poptmps (stix, 2);
if (!*rem) return STIX_NULL;
if (!r) return STIX_NULL;
{ int i;
printf ("REM=>");
for (i = STIX_OBJ_GET_SIZE(*rem); i > 0;)
if (r != STIX_SMOOI_TO_OOP(0) && modulo)
{
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);
if (rem)
{
stix_pushtmp (stix, &z);
stix_pushtmp (stix, &y);
r = stix_addints (stix, r, y);
stix_poptmps (stix, 2);
if (!r) return STIX_NULL;
stix_pushtmp (stix, &r);
z = normalize_bigint (stix, z);
stix_poptmp (stix);
if (!z) return STIX_NULL;
stix_pushtmp (stix, rem);
stix_pushtmp (stix, &r);
z = stix_subints (stix, z, STIX_SMOOI_TO_OOP(1));
stix_poptmp (stix);
*rem = r;
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)
else
{
/* remainder is not needed at all */
/* TODO: subtract 1 without normalization??? */
z = normalize_bigint (stix, z);
if (!z) return STIX_NULL;
return stix_subints (stix, z, STIX_SMOOI_TO_OOP(1));
}
}
}
else
{
stix_pushtmp (stix, &z);
r = normalize_bigint (stix, r);
stix_poptmp (stix);
if (!r) return STIX_NULL;
}
if (rem) *rem = r;
return normalize_bigint (stix, z);
}

View File

@ -115,6 +115,24 @@ void print_object (stix_t* stix, stix_oop_t oop)
printf ("$%.*s", (int)bcslen, bcs);
}
}
else if (STIX_OBJ_GET_CLASS(oop) == stix->_large_negative_integer)
{
stix_oow_t i;
printf ("-16r");
for (i = STIX_OBJ_GET_SIZE(oop); i > 0;)
{
printf ("%0*lX", (int)(STIX_SIZEOF(stix_liw_t) * 2), (unsigned long)((stix_oop_liword_t)oop)->slot[--i]);
}
}
else if (STIX_OBJ_GET_CLASS(oop) == stix->_large_positive_integer)
{
stix_oow_t i;
printf ("16r");
for (i = STIX_OBJ_GET_SIZE(oop); i > 0;)
{
printf ("%0*lX", (int)(STIX_SIZEOF(stix_liw_t) * 2), (unsigned long)((stix_oop_liword_t)oop)->slot[--i]);
}
}
else
{
stix_oop_class_t c;