enhanced stix_divints() to handle modulo/remainder more clearly
This commit is contained in:
parent
d8da07cb59
commit
fe8b6dfa24
@ -59,6 +59,19 @@
|
|||||||
self primitiveFailed.
|
self primitiveFailed.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#method // aNumber
|
||||||
|
{
|
||||||
|
<primitive: #_integer_quo2>
|
||||||
|
self primitiveFailed.
|
||||||
|
}
|
||||||
|
|
||||||
|
#method \\ aNumber
|
||||||
|
{
|
||||||
|
<primitive: #_integer_rem2>
|
||||||
|
self primitiveFailed.
|
||||||
|
}
|
||||||
|
|
||||||
#method = aNumber
|
#method = aNumber
|
||||||
{
|
{
|
||||||
<primitive: #_integer_eq>
|
<primitive: #_integer_eq>
|
||||||
|
@ -270,8 +270,14 @@ PROCESS TESTING
|
|||||||
|
|
||||||
(2r111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111 * 128971234897128931) dump.
|
(2r111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111 * 128971234897128931) dump.
|
||||||
|
|
||||||
(-10000 rem: -3) dump.
|
"(-10000 rem: 3) dump.
|
||||||
(-10000 quo: -3) dump.
|
(-10000 quo: 3) dump.
|
||||||
|
(-10000 \\ 3) dump.
|
||||||
|
(-10000 // 3) dump."
|
||||||
|
(7 rem: -3) dump.
|
||||||
|
(7 quo: -3) dump.
|
||||||
|
(7 \\ -3) dump.
|
||||||
|
(7 // -3) dump.
|
||||||
|
|
||||||
"
|
"
|
||||||
FFI isNil dump.
|
FFI isNil dump.
|
||||||
|
@ -1034,7 +1034,7 @@ oops_einval:
|
|||||||
return STIX_NULL;
|
return STIX_NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
stix_oop_t stix_divints (stix_t* stix, stix_oop_t x, stix_oop_t y, 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 t;
|
||||||
|
|
||||||
@ -1054,9 +1054,50 @@ stix_oop_t stix_divints (stix_t* stix, stix_oop_t x, stix_oop_t y, stix_oop_t* r
|
|||||||
q = xv / yv;
|
q = xv / yv;
|
||||||
STIX_ASSERT (STIX_IN_SMOOI_RANGE(q));
|
STIX_ASSERT (STIX_IN_SMOOI_RANGE(q));
|
||||||
|
|
||||||
|
r = xv - yv * q; /* xv % yv; */
|
||||||
|
if (modulo)
|
||||||
|
{
|
||||||
|
/* modulo */
|
||||||
|
/*
|
||||||
|
xv yv q r
|
||||||
|
-------------------------
|
||||||
|
7 3 2 1
|
||||||
|
-7 3 -3 2
|
||||||
|
7 -3 -3 -2
|
||||||
|
-7 -3 2 -1
|
||||||
|
*/
|
||||||
|
if (r && ((yv ^ r) < 0))
|
||||||
|
{
|
||||||
|
/* if the divisor has a different sign from r,
|
||||||
|
* change the sign of r to the divisor's sign */
|
||||||
|
r += yv;
|
||||||
|
--q;
|
||||||
|
STIX_ASSERT (r && ((yv ^ r) >= 0));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
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,
|
||||||
|
* change the sign of r to the dividend's sign */
|
||||||
|
r -= yv;
|
||||||
|
++q;
|
||||||
|
STIX_ASSERT (xv && ((xv ^ r) >= 0));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (rem)
|
if (rem)
|
||||||
{
|
{
|
||||||
r = xv - yv * q; /* r = xv % yv; */
|
|
||||||
STIX_ASSERT (STIX_IN_SMOOI_RANGE(r));
|
STIX_ASSERT (STIX_IN_SMOOI_RANGE(r));
|
||||||
*rem = STIX_SMOOI_TO_OOP(r);
|
*rem = STIX_SMOOI_TO_OOP(r);
|
||||||
}
|
}
|
||||||
|
@ -1069,7 +1069,7 @@ static int prim_integer_quo (stix_t* stix, stix_ooi_t nargs)
|
|||||||
rcv = ACTIVE_STACK_GET(stix, stix->sp - 1);
|
rcv = ACTIVE_STACK_GET(stix, stix->sp - 1);
|
||||||
arg = ACTIVE_STACK_GET(stix, stix->sp);
|
arg = ACTIVE_STACK_GET(stix, stix->sp);
|
||||||
|
|
||||||
quo = stix_divints (stix, rcv, arg, STIX_NULL);
|
quo = stix_divints (stix, rcv, arg, 0, STIX_NULL);
|
||||||
if (!quo) return (stix->errnum == STIX_EINVAL? 0: -1); /* soft or hard failure */
|
if (!quo) return (stix->errnum == STIX_EINVAL? 0: -1); /* soft or hard failure */
|
||||||
|
|
||||||
ACTIVE_STACK_POP (stix);
|
ACTIVE_STACK_POP (stix);
|
||||||
@ -1086,7 +1086,41 @@ static int prim_integer_rem (stix_t* stix, stix_ooi_t nargs)
|
|||||||
rcv = ACTIVE_STACK_GET(stix, stix->sp - 1);
|
rcv = ACTIVE_STACK_GET(stix, stix->sp - 1);
|
||||||
arg = ACTIVE_STACK_GET(stix, stix->sp);
|
arg = ACTIVE_STACK_GET(stix, stix->sp);
|
||||||
|
|
||||||
quo = stix_divints (stix, rcv, arg, &rem);
|
quo = stix_divints (stix, rcv, arg, 0, &rem);
|
||||||
|
if (!quo) return (stix->errnum == STIX_EINVAL? 0: -1); /* soft or hard failure */
|
||||||
|
|
||||||
|
ACTIVE_STACK_POP (stix);
|
||||||
|
ACTIVE_STACK_SETTOP (stix, rem);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int prim_integer_quo2 (stix_t* stix, stix_ooi_t nargs)
|
||||||
|
{
|
||||||
|
stix_oop_t rcv, arg, quo;
|
||||||
|
|
||||||
|
STIX_ASSERT (nargs == 1);
|
||||||
|
|
||||||
|
rcv = ACTIVE_STACK_GET(stix, stix->sp - 1);
|
||||||
|
arg = ACTIVE_STACK_GET(stix, stix->sp);
|
||||||
|
|
||||||
|
quo = stix_divints (stix, rcv, arg, 1, STIX_NULL);
|
||||||
|
if (!quo) return (stix->errnum == STIX_EINVAL? 0: -1); /* soft or hard failure */
|
||||||
|
|
||||||
|
ACTIVE_STACK_POP (stix);
|
||||||
|
ACTIVE_STACK_SETTOP (stix, quo);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int prim_integer_rem2 (stix_t* stix, stix_ooi_t nargs)
|
||||||
|
{
|
||||||
|
stix_oop_t rcv, arg, quo, rem;
|
||||||
|
|
||||||
|
STIX_ASSERT (nargs == 1);
|
||||||
|
|
||||||
|
rcv = ACTIVE_STACK_GET(stix, stix->sp - 1);
|
||||||
|
arg = ACTIVE_STACK_GET(stix, stix->sp);
|
||||||
|
|
||||||
|
quo = stix_divints (stix, rcv, arg, 1, &rem);
|
||||||
if (!quo) return (stix->errnum == STIX_EINVAL? 0: -1); /* soft or hard failure */
|
if (!quo) return (stix->errnum == STIX_EINVAL? 0: -1); /* soft or hard failure */
|
||||||
|
|
||||||
ACTIVE_STACK_POP (stix);
|
ACTIVE_STACK_POP (stix);
|
||||||
@ -1601,6 +1635,8 @@ static prim_t primitives[] =
|
|||||||
{ 1, prim_integer_mul, "_integer_mul" },
|
{ 1, prim_integer_mul, "_integer_mul" },
|
||||||
{ 1, prim_integer_quo, "_integer_quo" },
|
{ 1, prim_integer_quo, "_integer_quo" },
|
||||||
{ 1, prim_integer_rem, "_integer_rem" },
|
{ 1, prim_integer_rem, "_integer_rem" },
|
||||||
|
{ 1, prim_integer_quo2, "_integer_quo2" },
|
||||||
|
{ 1, prim_integer_rem2, "_integer_rem2" },
|
||||||
{ 1, prim_integer_eq, "_integer_eq" },
|
{ 1, prim_integer_eq, "_integer_eq" },
|
||||||
{ 1, prim_integer_ne, "_integer_ne" },
|
{ 1, prim_integer_ne, "_integer_ne" },
|
||||||
{ 1, prim_integer_lt, "_integer_lt" },
|
{ 1, prim_integer_lt, "_integer_lt" },
|
||||||
|
@ -1093,6 +1093,7 @@ stix_oop_t stix_divints (
|
|||||||
stix_t* stix,
|
stix_t* stix,
|
||||||
stix_oop_t x,
|
stix_oop_t x,
|
||||||
stix_oop_t y,
|
stix_oop_t y,
|
||||||
|
int modulo,
|
||||||
stix_oop_t* rem
|
stix_oop_t* rem
|
||||||
);
|
);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user