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,47 +1144,50 @@ 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 (modulo)
|
if (r)
|
||||||
{
|
{
|
||||||
/* modulo */
|
if (modulo)
|
||||||
/*
|
{
|
||||||
xv yv q r
|
/* modulo */
|
||||||
-------------------------
|
/*
|
||||||
7 3 2 1
|
xv yv q r
|
||||||
-7 3 -3 2
|
-------------------------
|
||||||
7 -3 -3 -2
|
7 3 2 1
|
||||||
-7 -3 2 -1
|
-7 3 -3 2
|
||||||
*/
|
7 -3 -3 -2
|
||||||
|
-7 -3 2 -1
|
||||||
|
*/
|
||||||
|
|
||||||
/* r must be floored. that is, it rounds away from zero
|
/* r must be floored. that is, it rounds away from zero
|
||||||
* and towards negative infinity */
|
* and towards negative infinity */
|
||||||
if (r && ((yv ^ r) < 0))
|
if (r && ((yv ^ r) < 0))
|
||||||
{
|
{
|
||||||
/* if the divisor has a different sign from r,
|
/* if the divisor has a different sign from r,
|
||||||
* change the sign of r to the divisor's sign */
|
* change the sign of r to the divisor's sign */
|
||||||
r += yv;
|
r += yv;
|
||||||
--q;
|
--q;
|
||||||
STIX_ASSERT (r && ((yv ^ r) >= 0));
|
STIX_ASSERT (r && ((yv ^ r) >= 0));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
else
|
||||||
else
|
|
||||||
{
|
|
||||||
/* remainder */
|
|
||||||
/*
|
|
||||||
xv yv q r
|
|
||||||
-------------------------
|
|
||||||
7 3 2 1
|
|
||||||
-7 3 -2 -1
|
|
||||||
7 -3 -2 1
|
|
||||||
-7 -3 2 -1
|
|
||||||
*/
|
|
||||||
if (xv && ((xv ^ r) < 0))
|
|
||||||
{
|
{
|
||||||
/* if the dividend has a different sign from r,
|
/* remainder */
|
||||||
* change the sign of r to the dividend's sign */
|
/*
|
||||||
r -= yv;
|
xv yv q r
|
||||||
++q;
|
-------------------------
|
||||||
STIX_ASSERT (xv && ((xv ^ r) >= 0));
|
7 3 2 1
|
||||||
|
-7 3 -2 -1
|
||||||
|
7 -3 -2 1
|
||||||
|
-7 -3 2 -1
|
||||||
|
*/
|
||||||
|
if (xv && ((xv ^ r) < 0))
|
||||||
|
{
|
||||||
|
/* if the dividend has a different sign from r,
|
||||||
|
* change the sign of r to the dividend's sign */
|
||||||
|
r -= yv;
|
||||||
|
++q;
|
||||||
|
STIX_ASSERT (xv && ((xv ^ r) >= 0));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -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;
|
if (x_neg)
|
||||||
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)
|
|
||||||
{
|
{
|
||||||
|
/* 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, &z);
|
||||||
*rem = normalize_bigint (stix, *rem);
|
stix_pushtmp (stix, &y);
|
||||||
stix_poptmp (stix);
|
r = normalize_bigint (stix, r);
|
||||||
if (!*rem) return STIX_NULL;
|
stix_poptmps (stix, 2);
|
||||||
|
if (!r) return STIX_NULL;
|
||||||
|
|
||||||
if (x_neg)
|
if (r != STIX_SMOOI_TO_OOP(0) && modulo)
|
||||||
{
|
{
|
||||||
STIX_OBJ_SET_CLASS(*rem, stix->_large_negative_integer);
|
if (rem)
|
||||||
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, &z);
|
||||||
stix_pushtmp (stix, &y);
|
stix_pushtmp (stix, &y);
|
||||||
*rem = stix_addints (stix, *rem, y);
|
r = stix_addints (stix, r, y);
|
||||||
stix_poptmps (stix, 2);
|
stix_poptmps (stix, 2);
|
||||||
if (!*rem) return STIX_NULL;
|
if (!r) return STIX_NULL;
|
||||||
|
|
||||||
{ int i;
|
stix_pushtmp (stix, &r);
|
||||||
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);
|
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
|
||||||
|
{
|
||||||
|
/* 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));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
{ 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
|
||||||
{
|
{
|
||||||
z = normalize_bigint (stix, z);
|
stix_pushtmp (stix, &z);
|
||||||
return stix_subints (stix, z, STIX_SMOOI_TO_OOP(1));
|
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