added the missing zero check in stix_divint()
This commit is contained in:
parent
a32e1903bf
commit
addd201beb
@ -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.
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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;
|
||||||
|
Loading…
Reference in New Issue
Block a user