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 // 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 isNil dump.
FFI notNil 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)y)->slot, STIX_OBJ_GET_SIZE(y),
((stix_oop_liword_t)qq)->slot, ((stix_oop_liword_t)rr)->slot); ((stix_oop_liword_t)qq)->slot, ((stix_oop_liword_t)rr)->slot);
if (r) *r = rr; *r = rr;
return qq; 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 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; 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))
@ -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): * mathematical relationship (all variables are integers):
* a/b = q with remainder r * a/b = q with remainder r
* such that * 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 * If you want the relationship to extend for negative a
* (keeping b positive), you have two choices: if you truncate q * (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)); STIX_ASSERT (STIX_IN_SMOOI_RANGE(q));
r = xv - yv * q; /* xv % yv; */ r = xv - yv * q; /* xv % yv; */
if (r)
{
if (modulo) if (modulo)
{ {
/* 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)); STIX_ASSERT (xv && ((xv ^ r) >= 0));
} }
} }
}
if (rem) if (rem)
{ {
@ -1256,86 +1259,64 @@ DO SHIFTING.
stix_pushtmp (stix, &x); stix_pushtmp (stix, &x);
stix_pushtmp (stix, &y); stix_pushtmp (stix, &y);
z = divide_unsigned_integers (stix, x, y, rem); z = divide_unsigned_integers (stix, x, y, &r);
stix_poptmps (stix, 2); stix_poptmps (stix, 2);
if (!z) return STIX_NULL; if (!z) return STIX_NULL;
if (x_neg != y_neg) if (x_neg != y_neg) STIX_OBJ_SET_CLASS(z, stix->_large_negative_integer);
{
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) if (x_neg)
{ {
STIX_OBJ_SET_CLASS(*rem, stix->_large_negative_integer); /* the class on r must be set before normalize_bigint()
if (modulo) * because it can turn it to a small integer */
{ STIX_OBJ_SET_CLASS(r, stix->_large_negative_integer);
{ 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, &z);
stix_pushtmp (stix, &y); stix_pushtmp (stix, &y);
*rem = stix_addints (stix, *rem, y); r = normalize_bigint (stix, r);
stix_poptmps (stix, 2); stix_poptmps (stix, 2);
if (!*rem) return STIX_NULL; if (!r) return STIX_NULL;
{ int i; if (r != STIX_SMOOI_TO_OOP(0) && modulo)
printf ("REM=>"); {
for (i = STIX_OBJ_GET_SIZE(*rem); i > 0;) if (rem)
{ {
printf ("%0*lX ", (int)(STIX_SIZEOF(stix_liw_t) * 2), (unsigned long)((stix_oop_liword_t)*rem)->slot[--i]); stix_pushtmp (stix, &z);
} stix_pushtmp (stix, &y);
printf ("\n"); r = stix_addints (stix, r, y);
} stix_poptmps (stix, 2);
stix_pushtmp (stix, rem); if (!r) return STIX_NULL;
stix_pushtmp (stix, &r);
z = normalize_bigint (stix, z); z = normalize_bigint (stix, z);
stix_poptmp (stix); stix_poptmp (stix);
if (!z) return STIX_NULL; if (!z) return STIX_NULL;
stix_pushtmp (stix, rem); stix_pushtmp (stix, &r);
z = stix_subints (stix, z, STIX_SMOOI_TO_OOP(1)); z = stix_subints (stix, z, STIX_SMOOI_TO_OOP(1));
stix_poptmp (stix); stix_poptmp (stix);
*rem = r;
return z; return z;
} }
} else
{ 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)
{ {
/* remainder is not needed at all */
/* TODO: subtract 1 without normalization??? */
z = normalize_bigint (stix, z); z = normalize_bigint (stix, z);
if (!z) return STIX_NULL;
return stix_subints (stix, z, STIX_SMOOI_TO_OOP(1)); 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); 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); 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 else
{ {
stix_oop_class_t c; stix_oop_class_t c;