added stix_bitinvint()

This commit is contained in:
hyunghwan.chung 2015-12-17 16:37:26 +00:00
parent 08cfa55acc
commit 23d8d17b08
5 changed files with 112 additions and 9 deletions

View File

@ -128,9 +128,7 @@
#method bitInvert #method bitInvert
{ {
##<primitive: #_integer_bitinvert> <primitive: #_integer_bitinv>
##self primitiveFailed.
^-1 - self. ^-1 - self.
} }

View File

@ -352,6 +352,8 @@ PROCESS TESTING
((16r1234 bitXor: -2r100000000000000000000000000000000000000000000000000000000000000000000000000000) printStringRadix: 16) dump. ((16r1234 bitXor: -2r100000000000000000000000000000000000000000000000000000000000000000000000000000) printStringRadix: 16) dump.
((-16r1234 bitXor: -2r100000000000000000000000000000000000000000000000000000000000000000000000000000) printStringRadix: 16) dump. ((-16r1234 bitXor: -2r100000000000000000000000000000000000000000000000000000000000000000000000000000) printStringRadix: 16) dump.
((2r100000000000000000000000000000000000000000000000000000000000000000000000000000 bitInvert) printStringRadix: 16) dump.
((2r1111111 bitInvert) printStringRadix: 16) dump
" "
FFI isNil dump. FFI isNil dump.

View File

@ -736,7 +736,6 @@ static void divide_unsigned_array (
static stix_oop_t add_unsigned_integers (stix_t* stix, stix_oop_t x, stix_oop_t y) static stix_oop_t add_unsigned_integers (stix_t* stix, stix_oop_t x, stix_oop_t y)
{ {
stix_liw_t* a, * b;
stix_oow_t as, bs, zs; stix_oow_t as, bs, zs;
stix_oop_t z; stix_oop_t z;
@ -752,16 +751,22 @@ static stix_oop_t add_unsigned_integers (stix_t* stix, stix_oop_t x, stix_oop_t
if (as >= bs) if (as >= bs)
{ {
a = ((stix_oop_liword_t)x)->slot; add_unsigned_array (
b = ((stix_oop_liword_t)y)->slot; ((stix_oop_liword_t)x)->slot, as,
((stix_oop_liword_t)y)->slot, bs,
((stix_oop_liword_t)z)->slot
);
} }
else else
{ {
a = ((stix_oop_liword_t)y)->slot; add_unsigned_array (
b = ((stix_oop_liword_t)x)->slot; ((stix_oop_liword_t)y)->slot, bs,
((stix_oop_liword_t)x)->slot, as,
((stix_oop_liword_t)z)->slot
);
} }
add_unsigned_array (a, as, b, bs, ((stix_oop_liword_t)z)->slot);
return z; return z;
} }
@ -2014,6 +2019,82 @@ oops_einval:
return STIX_NULL; return STIX_NULL;
} }
stix_oop_t stix_bitinvint (stix_t* stix, stix_oop_t x)
{
if (STIX_OOP_IS_SMOOI(x))
{
stix_ooi_t v;
v = STIX_OOP_TO_SMOOI(x);
v = ~v;
if (STIX_IN_SMOOI_RANGE(v)) return STIX_SMOOI_TO_OOP(v);
return make_bigint_with_ooi (stix, v);
}
else
{
stix_oop_t z;
stix_oow_t i, xs, zs, zalloc;
int negx;
xs = STIX_OBJ_GET_SIZE(x);
negx = (STIX_OBJ_GET_CLASS(x) == stix->_large_negative_integer)? 1: 0;
if (negx)
{
zalloc = xs;
zs = xs;
}
else
{
zalloc = xs + 1;
zs = xs;
}
stix_pushtmp (stix, &x);
z = stix_instantiate (stix, stix->_large_positive_integer, STIX_NULL, zalloc);
stix_poptmp (stix);
if (!z) return STIX_NULL;
if (negx)
{
stix_lidw_t w, carry;
carry = 1;
for (i = 0; i < xs; i++)
{
w = (stix_lidw_t)(~((stix_oop_liword_t)x)->slot[i]) + carry;
carry = w >> STIX_LIW_BITS;
((stix_oop_liword_t)z)->slot[i] = ~(stix_liw_t)w;
}
STIX_ASSERT (carry == 0);
}
else
{
stix_lidw_t w, carry;
for (i = 0; i < xs; i++)
{
((stix_oop_liword_t)z)->slot[i] = ~((stix_oop_liword_t)x)->slot[i];
}
/* 2's complement on the final result */
((stix_oop_liword_t)z)->slot[zs] = STIX_TYPE_MAX(stix_liw_t);
carry = 1;
for (i = 0; i <= zs; i++)
{
w = (stix_lidw_t)(~((stix_oop_liword_t)z)->slot[i]) + carry;
carry = w >> STIX_LIW_BITS;
((stix_oop_liword_t)z)->slot[i] = (stix_liw_t)w;
}
STIX_ASSERT (carry == 0);
STIX_OBJ_SET_CLASS (z, stix->_large_negative_integer);
}
return normalize_bigint(stix, z);
}
}
static stix_uint8_t ooch_val_tab[] = static stix_uint8_t ooch_val_tab[] =
{ {

View File

@ -1240,6 +1240,22 @@ static int prim_integer_bitxor (stix_t* stix, stix_ooi_t nargs)
return 1; return 1;
} }
static int prim_integer_bitinv (stix_t* stix, stix_ooi_t nargs)
{
stix_oop_t rcv, res;
STIX_ASSERT (nargs == 0);
rcv = ACTIVE_STACK_GET(stix, stix->sp);
res = stix_bitinvint (stix, rcv);
if (!res) return (stix->errnum == STIX_EINVAL? 0: -1); /* soft or hard failure */
ACTIVE_STACK_POP (stix);
ACTIVE_STACK_SETTOP (stix, res);
return 1;
}
static int prim_integer_eq (stix_t* stix, stix_ooi_t nargs) static int prim_integer_eq (stix_t* stix, stix_ooi_t nargs)
{ {
stix_oop_t rcv, arg; stix_oop_t rcv, arg;
@ -1785,6 +1801,7 @@ static prim_t primitives[] =
{ 1, prim_integer_bitand, "_integer_bitand" }, { 1, prim_integer_bitand, "_integer_bitand" },
{ 1, prim_integer_bitor, "_integer_bitor" }, { 1, prim_integer_bitor, "_integer_bitor" },
{ 1, prim_integer_bitxor, "_integer_bitxor" }, { 1, prim_integer_bitxor, "_integer_bitxor" },
{ 0, prim_integer_bitinv, "_integer_bitinv" },
{ 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" },

View File

@ -1124,6 +1124,11 @@ stix_oop_t stix_bitxorints (
stix_oop_t y stix_oop_t y
); );
stix_oop_t stix_bitinvint (
stix_t* stix,
stix_oop_t x
);
stix_oop_t stix_strtoint ( stix_oop_t stix_strtoint (
stix_t* stix, stix_t* stix,
const stix_ooch_t* str, const stix_ooch_t* str,