added stix_bitinvint()
This commit is contained in:
parent
08cfa55acc
commit
23d8d17b08
@ -128,9 +128,7 @@
|
||||
|
||||
#method bitInvert
|
||||
{
|
||||
##<primitive: #_integer_bitinvert>
|
||||
##self primitiveFailed.
|
||||
|
||||
<primitive: #_integer_bitinv>
|
||||
^-1 - self.
|
||||
}
|
||||
|
||||
|
@ -352,6 +352,8 @@ PROCESS TESTING
|
||||
((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.
|
||||
|
@ -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)
|
||||
{
|
||||
stix_liw_t* a, * b;
|
||||
stix_oow_t as, bs, zs;
|
||||
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)
|
||||
{
|
||||
a = ((stix_oop_liword_t)x)->slot;
|
||||
b = ((stix_oop_liword_t)y)->slot;
|
||||
add_unsigned_array (
|
||||
((stix_oop_liword_t)x)->slot, as,
|
||||
((stix_oop_liword_t)y)->slot, bs,
|
||||
((stix_oop_liword_t)z)->slot
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
a = ((stix_oop_liword_t)y)->slot;
|
||||
b = ((stix_oop_liword_t)x)->slot;
|
||||
add_unsigned_array (
|
||||
((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;
|
||||
}
|
||||
|
||||
@ -2014,6 +2019,82 @@ oops_einval:
|
||||
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[] =
|
||||
{
|
||||
|
@ -1240,6 +1240,22 @@ static int prim_integer_bitxor (stix_t* stix, stix_ooi_t nargs)
|
||||
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)
|
||||
{
|
||||
stix_oop_t rcv, arg;
|
||||
@ -1785,6 +1801,7 @@ static prim_t primitives[] =
|
||||
{ 1, prim_integer_bitand, "_integer_bitand" },
|
||||
{ 1, prim_integer_bitor, "_integer_bitor" },
|
||||
{ 1, prim_integer_bitxor, "_integer_bitxor" },
|
||||
{ 0, prim_integer_bitinv, "_integer_bitinv" },
|
||||
{ 1, prim_integer_eq, "_integer_eq" },
|
||||
{ 1, prim_integer_ne, "_integer_ne" },
|
||||
{ 1, prim_integer_lt, "_integer_lt" },
|
||||
|
@ -1124,6 +1124,11 @@ stix_oop_t stix_bitxorints (
|
||||
stix_oop_t y
|
||||
);
|
||||
|
||||
stix_oop_t stix_bitinvint (
|
||||
stix_t* stix,
|
||||
stix_oop_t x
|
||||
);
|
||||
|
||||
stix_oop_t stix_strtoint (
|
||||
stix_t* stix,
|
||||
const stix_ooch_t* str,
|
||||
|
Loading…
Reference in New Issue
Block a user