enhanced stix_inttostr() to handle a power-of-2 radix more efficiently
This commit is contained in:
parent
95ceac9e85
commit
5bf467cb29
@ -132,6 +132,12 @@
|
|||||||
^-1 - self.
|
^-1 - self.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#method bitShift: aNumber
|
||||||
|
{
|
||||||
|
<primitive: #_integer_bitshift>
|
||||||
|
self primitiveFailed.
|
||||||
|
}
|
||||||
|
|
||||||
#method asString
|
#method asString
|
||||||
{
|
{
|
||||||
self printStringRadix: 10
|
self printStringRadix: 10
|
||||||
|
@ -353,7 +353,15 @@ PROCESS TESTING
|
|||||||
((-16r1234 bitXor: -2r100000000000000000000000000000000000000000000000000000000000000000000000000000) printStringRadix: 16) dump.
|
((-16r1234 bitXor: -2r100000000000000000000000000000000000000000000000000000000000000000000000000000) printStringRadix: 16) dump.
|
||||||
|
|
||||||
((2r100000000000000000000000000000000000000000000000000000000000000000000000000000 bitInvert) printStringRadix: 16) dump.
|
((2r100000000000000000000000000000000000000000000000000000000000000000000000000000 bitInvert) printStringRadix: 16) dump.
|
||||||
((2r1111111 bitInvert) printStringRadix: 16) dump
|
((2r1111111 bitInvert) printStringRadix: 16) dump.
|
||||||
|
((2r11001110000000000000000000000000000000000000000000000000000000000000000000000 bitInvert) printStringRadix: 16) dump.
|
||||||
|
|
||||||
|
((2r1111 bitShift: 100) printStringRadix: 2) dump.
|
||||||
|
((123123124 bitShift: 100000) printStringRadix: 16) dump.
|
||||||
|
(2r110101010101010101010101010101111111111111111111111111111111111111111111111111111111100000000001111111 printStringRadix: 16) dump.
|
||||||
|
|
||||||
|
(16rFFFFFFFFFF1234567890AAAAAAAAAAAAAAAAAAAAAAAAA22222222222222222F printStringRadix: 32) dump.
|
||||||
|
(32r3VVVVVVVS938LJOI2LALALALALALALALALAL8H248H248H248HF printStringRadix: 16) dump.
|
||||||
|
|
||||||
"
|
"
|
||||||
FFI isNil dump.
|
FFI isNil dump.
|
||||||
|
@ -38,6 +38,17 @@
|
|||||||
/*#define IS_POWER_OF_2(ui) (((ui) > 0) && (((ui) & (~(ui)+ 1)) == (ui)))*/
|
/*#define IS_POWER_OF_2(ui) (((ui) > 0) && (((ui) & (~(ui)+ 1)) == (ui)))*/
|
||||||
#define IS_POWER_OF_2(ui) (((ui) > 0) && ((ui) & ((ui) - 1)) == 0)
|
#define IS_POWER_OF_2(ui) (((ui) > 0) && ((ui) & ((ui) - 1)) == 0)
|
||||||
|
|
||||||
|
/* digit character array */
|
||||||
|
static char* _digitc = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
|
||||||
|
|
||||||
|
/* exponent table */
|
||||||
|
static stix_uint8_t _exp_tab[] =
|
||||||
|
{
|
||||||
|
0, 0, 1, 0, 2, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 4,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
#if (STIX_SIZEOF_OOW_T == STIX_SIZEOF_INT) && defined(STIX_HAVE_BUILTIN_UADD_OVERFLOW)
|
#if (STIX_SIZEOF_OOW_T == STIX_SIZEOF_INT) && defined(STIX_HAVE_BUILTIN_UADD_OVERFLOW)
|
||||||
# define oow_add_overflow(a,b,c) __builtin_uadd_overflow(a,b,c)
|
# define oow_add_overflow(a,b,c) __builtin_uadd_overflow(a,b,c)
|
||||||
#elif (STIX_SIZEOF_OOW_T == STIX_SIZEOF_LONG) && defined(STIX_HAVE_BUILTIN_UADDL_OVERFLOW)
|
#elif (STIX_SIZEOF_OOW_T == STIX_SIZEOF_LONG) && defined(STIX_HAVE_BUILTIN_UADDL_OVERFLOW)
|
||||||
@ -167,6 +178,8 @@ static STIX_INLINE int is_integer (stix_t* stix, stix_oop_t oop)
|
|||||||
c == stix->_large_negative_integer;
|
c == stix->_large_negative_integer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static STIX_INLINE stix_oop_t make_bigint_with_ooi (stix_t* stix, stix_ooi_t i)
|
static STIX_INLINE stix_oop_t make_bigint_with_ooi (stix_t* stix, stix_ooi_t i)
|
||||||
{
|
{
|
||||||
#if (STIX_LIW_BITS == STIX_OOW_BITS)
|
#if (STIX_LIW_BITS == STIX_OOW_BITS)
|
||||||
@ -211,6 +224,61 @@ static STIX_INLINE stix_oop_t make_bigint_with_ooi (stix_t* stix, stix_ooi_t i)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static STIX_INLINE stix_oop_t make_bloated_bigint_with_ooi (stix_t* stix, stix_ooi_t i, stix_oow_t extra)
|
||||||
|
{
|
||||||
|
#if (STIX_LIW_BITS == STIX_OOW_BITS)
|
||||||
|
stix_oow_t w;
|
||||||
|
stix_oop_t z;
|
||||||
|
|
||||||
|
STIX_ASSERT (extra <= STIX_TYPE_MAX(stix_oow_t) - 1);
|
||||||
|
STIX_ASSERT (STIX_SIZEOF(stix_oow_t) == STIX_SIZEOF(stix_liw_t));
|
||||||
|
if (i >= 0)
|
||||||
|
{
|
||||||
|
w = i;
|
||||||
|
z =stix_instantiate (stix, stix->_large_positive_integer, STIX_NULL, 1 + extra);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
STIX_ASSERT (i > STIX_TYPE_MIN(stix_ooi_t));
|
||||||
|
w = -i;
|
||||||
|
z = stix_instantiate (stix, stix->_large_negative_integer, STIX_NULL, 1 + extra);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!z) return STIX_NULL;
|
||||||
|
((stix_oop_liword_t)z)->slot[0] = w;
|
||||||
|
return z;
|
||||||
|
|
||||||
|
#elif (STIX_LIW_BITS == STIX_OOHW_BITS)
|
||||||
|
stix_liw_t hw[2];
|
||||||
|
stix_oow_t w;
|
||||||
|
stix_oop_t z;
|
||||||
|
|
||||||
|
STIX_ASSERT (extra <= STIX_TYPE_MAX(stix_oow_t) - 2);
|
||||||
|
if (i >= 0)
|
||||||
|
{
|
||||||
|
w = i;
|
||||||
|
hw[0] = w & STIX_LBMASK(stix_oow_t,STIX_LIW_BITS);
|
||||||
|
hw[1] = w >> STIX_LIW_BITS;
|
||||||
|
z = stix_instantiate (stix, stix->_large_positive_integer, STIX_NULL, (hw[1] > 0? 2: 1) + extra);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
STIX_ASSERT (i > STIX_TYPE_MIN(stix_ooi_t));
|
||||||
|
w = -i;
|
||||||
|
hw[0] = w & STIX_LBMASK(stix_oow_t,STIX_LIW_BITS);
|
||||||
|
hw[1] = w >> STIX_LIW_BITS;
|
||||||
|
z = stix_instantiate (stix, stix->_large_negative_integer, STIX_NULL, (hw[1] > 0? 2: 1) + extra);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!z) return STIX_NULL;
|
||||||
|
((stix_oop_liword_t)z)->slot[0] = hw[0];
|
||||||
|
if (hw[1] > 0) ((stix_oop_liword_t)z)->slot[1] = hw[1];
|
||||||
|
return z;
|
||||||
|
#else
|
||||||
|
# error UNSUPPORTED LIW BIT SIZE
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
static STIX_INLINE stix_oop_t make_bigint_with_intmax (stix_t* stix, stix_intmax_t v)
|
static STIX_INLINE stix_oop_t make_bigint_with_intmax (stix_t* stix, stix_intmax_t v)
|
||||||
{
|
{
|
||||||
stix_oow_t len;
|
stix_oow_t len;
|
||||||
@ -230,16 +298,6 @@ static STIX_INLINE stix_oop_t make_bigint_with_intmax (stix_t* stix, stix_intmax
|
|||||||
}
|
}
|
||||||
while (ui > 0);
|
while (ui > 0);
|
||||||
|
|
||||||
{ int i;
|
|
||||||
printf ("MKBI-INTMAX=>");
|
|
||||||
for (i = len; i > 0;)
|
|
||||||
{
|
|
||||||
|
|
||||||
printf ("%0*lX ", (int)(STIX_SIZEOF(stix_liw_t) * 2), (unsigned long)buf[--i]);
|
|
||||||
}
|
|
||||||
printf ("\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
return stix_instantiate (stix, ((v >= 0)? stix->_large_positive_integer: stix->_large_negative_integer), buf, len);
|
return stix_instantiate (stix, ((v >= 0)? stix->_large_positive_integer: stix->_large_negative_integer), buf, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -689,7 +747,8 @@ static void divide_unsigned_array (
|
|||||||
const stix_liw_t* y, stix_oow_t ys,
|
const stix_liw_t* y, stix_oow_t ys,
|
||||||
stix_liw_t* q, stix_liw_t* r)
|
stix_liw_t* q, stix_liw_t* r)
|
||||||
{
|
{
|
||||||
/* TODO: this function needs to be rewritten for performance improvement. */
|
/* TODO: this function needs to be rewritten for performance improvement.
|
||||||
|
* the binary long division is extremely slow for a big number */
|
||||||
|
|
||||||
/* Perform binary long division.
|
/* Perform binary long division.
|
||||||
* http://en.wikipedia.org/wiki/Division_algorithm
|
* http://en.wikipedia.org/wiki/Division_algorithm
|
||||||
@ -712,7 +771,6 @@ static void divide_unsigned_array (
|
|||||||
STIX_MEMSET (q, 0, STIX_SIZEOF(*q) * xs);
|
STIX_MEMSET (q, 0, STIX_SIZEOF(*q) * xs);
|
||||||
STIX_MEMSET (r, 0, STIX_SIZEOF(*q) * xs);
|
STIX_MEMSET (r, 0, STIX_SIZEOF(*q) * xs);
|
||||||
|
|
||||||
/*rs = 1; */
|
|
||||||
for (i = xs; i > 0; )
|
for (i = xs; i > 0; )
|
||||||
{
|
{
|
||||||
--i;
|
--i;
|
||||||
@ -730,7 +788,6 @@ static void divide_unsigned_array (
|
|||||||
STIX_SETBITS (stix_liw_t, q[i], j, 1, 1);
|
STIX_SETBITS (stix_liw_t, q[i], j, 1, 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/*if (xs > rs && r[rs] > 0) rs++;*/
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2037,6 +2094,8 @@ stix_oop_t stix_bitinvint (stix_t* stix, stix_oop_t x)
|
|||||||
stix_oow_t i, xs, zs, zalloc;
|
stix_oow_t i, xs, zs, zalloc;
|
||||||
int negx;
|
int negx;
|
||||||
|
|
||||||
|
if (!is_integer(stix,x)) goto oops_einval;
|
||||||
|
|
||||||
xs = STIX_OBJ_GET_SIZE(x);
|
xs = STIX_OBJ_GET_SIZE(x);
|
||||||
negx = (STIX_OBJ_GET_CLASS(x) == stix->_large_negative_integer)? 1: 0;
|
negx = (STIX_OBJ_GET_CLASS(x) == stix->_large_negative_integer)? 1: 0;
|
||||||
|
|
||||||
@ -2094,6 +2153,109 @@ stix_oop_t stix_bitinvint (stix_t* stix, stix_oop_t x)
|
|||||||
|
|
||||||
return normalize_bigint(stix, z);
|
return normalize_bigint(stix, z);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
oops_einval:
|
||||||
|
stix->errnum = STIX_EINVAL;
|
||||||
|
return STIX_NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
stix_oop_t stix_bitshiftint (stix_t* stix, stix_oop_t x, stix_oop_t y)
|
||||||
|
{
|
||||||
|
/* left shift if y is positive,
|
||||||
|
* right shift if y is negative */
|
||||||
|
|
||||||
|
if (STIX_OOP_IS_SMOOI(x) && STIX_OOP_IS_SMOOI(y))
|
||||||
|
{
|
||||||
|
stix_ooi_t v1, v2;
|
||||||
|
|
||||||
|
v1 = STIX_OOP_TO_SMOOI(x);
|
||||||
|
v2 = STIX_OOP_TO_SMOOI(y);
|
||||||
|
if (v1 == 0 || v2 == 0)
|
||||||
|
{
|
||||||
|
/* return without cloning as x is a small integer */
|
||||||
|
return x;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (v2 > 0)
|
||||||
|
{
|
||||||
|
/* left shift */
|
||||||
|
stix_oop_t z;
|
||||||
|
stix_oow_t wshift;
|
||||||
|
|
||||||
|
wshift = v2 / STIX_LIW_BITS;
|
||||||
|
if (v2 > wshift * STIX_LIW_BITS) wshift++;
|
||||||
|
|
||||||
|
z = make_bloated_bigint_with_ooi (stix, v1, wshift);
|
||||||
|
if (!z) return STIX_NULL;
|
||||||
|
|
||||||
|
lshift_unsigned_array (((stix_oop_liword_t)z)->slot, STIX_OBJ_GET_SIZE(z), v2);
|
||||||
|
return normalize_bigint (stix, z);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* right shift */
|
||||||
|
stix_ooi_t v;
|
||||||
|
/* TODO: ... */
|
||||||
|
/* right shift of a negative number is complex... */
|
||||||
|
v2 = -v2;
|
||||||
|
if (v2 >= STIX_OOI_BITS) return STIX_SMOOI_TO_OOP(0);
|
||||||
|
|
||||||
|
v = v1 >> v2;
|
||||||
|
if (STIX_IN_SMOOI_RANGE(v)) return STIX_SMOOI_TO_OOP(v);
|
||||||
|
return make_bigint_with_ooi (stix, v);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (STIX_OOP_IS_SMOOI(x))
|
||||||
|
{
|
||||||
|
stix_ooi_t v;
|
||||||
|
|
||||||
|
if (!is_integer(stix,y)) goto oops_einval;
|
||||||
|
|
||||||
|
v = STIX_OOP_TO_SMOOI(x);
|
||||||
|
if (v == 0) return STIX_SMOOI_TO_OOP(0);
|
||||||
|
|
||||||
|
stix_pushtmp (stix, &y);
|
||||||
|
x = make_bigint_with_ooi (stix, v);
|
||||||
|
stix_poptmp (stix);
|
||||||
|
if (!x) return STIX_NULL;
|
||||||
|
|
||||||
|
goto bigint_and_bigint;
|
||||||
|
}
|
||||||
|
else if (STIX_OOP_IS_SMOOI(y))
|
||||||
|
{
|
||||||
|
stix_ooi_t v;
|
||||||
|
|
||||||
|
if (!is_integer(stix,x)) goto oops_einval;
|
||||||
|
|
||||||
|
v = STIX_OOP_TO_SMOOI(y);
|
||||||
|
if (v == 0) return clone_bigint (stix, x, STIX_OBJ_GET_SIZE(x));
|
||||||
|
|
||||||
|
stix_pushtmp (stix, &x);
|
||||||
|
y = make_bigint_with_ooi (stix, v);
|
||||||
|
stix_poptmp (stix);
|
||||||
|
if (!y) return STIX_NULL;
|
||||||
|
|
||||||
|
goto bigint_and_bigint;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
stix_oop_t z;
|
||||||
|
int negx, negy;
|
||||||
|
|
||||||
|
if (!is_integer(stix,x) || !is_integer(stix, y)) goto oops_einval;
|
||||||
|
|
||||||
|
negx = (STIX_OBJ_GET_CLASS(x) == stix->_large_negative_integer)? 1: 0;
|
||||||
|
negy = (STIX_OBJ_GET_CLASS(y) == stix->_large_negative_integer)? 1: 0;
|
||||||
|
|
||||||
|
bigint_and_bigint:
|
||||||
|
|
||||||
|
/* TODO: */
|
||||||
|
return normalize_bigint(stix, z);
|
||||||
|
}
|
||||||
|
|
||||||
|
oops_einval:
|
||||||
|
stix->errnum = STIX_EINVAL;
|
||||||
|
return STIX_NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static stix_uint8_t ooch_val_tab[] =
|
static stix_uint8_t ooch_val_tab[] =
|
||||||
@ -2189,12 +2351,7 @@ stix_oop_t stix_strtoint (stix_t* stix, const stix_ooch_t* str, stix_oow_t len,
|
|||||||
|
|
||||||
/* TODO: PPC - use cntlz, cntlzw, cntlzd, SPARC - use lzcnt, MIPS clz */
|
/* TODO: PPC - use cntlz, cntlzw, cntlzd, SPARC - use lzcnt, MIPS clz */
|
||||||
#else
|
#else
|
||||||
static stix_uint8_t exp_tab[] =
|
exp = _exp_tab[radix];
|
||||||
{
|
|
||||||
0, 0, 1, 0, 2, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 4,
|
|
||||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0
|
|
||||||
};
|
|
||||||
exp = exp_tab[radix];
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* bytes */
|
/* bytes */
|
||||||
@ -2346,14 +2503,12 @@ oops_einval:
|
|||||||
static stix_oow_t oow_to_text (stix_oow_t w, int radix, stix_ooch_t* buf)
|
static stix_oow_t oow_to_text (stix_oow_t w, int radix, stix_ooch_t* buf)
|
||||||
{
|
{
|
||||||
stix_ooch_t* ptr;
|
stix_ooch_t* ptr;
|
||||||
static char* digitc = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
|
|
||||||
|
|
||||||
STIX_ASSERT (radix >= 2 && radix <= 36);
|
STIX_ASSERT (radix >= 2 && radix <= 36);
|
||||||
|
|
||||||
ptr = buf;
|
ptr = buf;
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
*ptr++ = digitc[w % radix];
|
*ptr++ = _digitc[w % radix];
|
||||||
w /= radix;
|
w /= radix;
|
||||||
}
|
}
|
||||||
while (w > 0);
|
while (w > 0);
|
||||||
@ -2448,20 +2603,57 @@ stix_oop_t stix_inttostr (stix_t* stix, stix_oop_t num, int radix)
|
|||||||
return stix_makestring (stix, buf, len);
|
return stix_makestring (stix, buf, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Do it in a hard way */
|
|
||||||
#if (STIX_LIW_BITS == STIX_OOW_BITS)
|
|
||||||
b[0] = stix->bigint[radix].multiplier; /* block divisor */
|
|
||||||
bs = 1;
|
|
||||||
#elif (STIX_LIW_BITS == STIX_OOHW_BITS)
|
|
||||||
b[0] = stix->bigint[radix].multiplier & STIX_LBMASK(stix_oow_t, STIX_OOHW_BITS);
|
|
||||||
b[1] = stix->bigint[radix].multiplier >> STIX_OOHW_BITS;
|
|
||||||
bs = (b[1] > 0)? 2: 1;
|
|
||||||
#else
|
|
||||||
# error UNSUPPORTED LIW BIT SIZE
|
|
||||||
#endif
|
|
||||||
|
|
||||||
as = STIX_OBJ_GET_SIZE(num);
|
as = STIX_OBJ_GET_SIZE(num);
|
||||||
|
|
||||||
|
if (IS_POWER_OF_2(radix))
|
||||||
|
{
|
||||||
|
unsigned int exp, accbits;
|
||||||
|
stix_lidw_t acc;
|
||||||
|
stix_oow_t xpos;
|
||||||
|
|
||||||
|
exp = _exp_tab[radix];
|
||||||
|
xlen = as * ((STIX_LIW_BITS + exp) / exp) + 1;
|
||||||
|
xpos = xlen;
|
||||||
|
|
||||||
|
xbuf = (stix_ooch_t*)stix_allocmem (stix, STIX_SIZEOF(*xbuf) * xlen);
|
||||||
|
if (!xbuf) return STIX_NULL;
|
||||||
|
|
||||||
|
acc = 0;
|
||||||
|
accbits = 0;
|
||||||
|
|
||||||
|
w = 0;
|
||||||
|
while (w < as)
|
||||||
|
{
|
||||||
|
acc |= (stix_lidw_t)((stix_oop_liword_t)num)->slot[w] << accbits;
|
||||||
|
accbits += STIX_LIW_BITS;
|
||||||
|
|
||||||
|
w++;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
xbuf[--xpos] = _digitc[acc & (radix - 1)]; /* acc % radix */
|
||||||
|
accbits -= exp;
|
||||||
|
acc >>= exp;
|
||||||
|
if (w < as)
|
||||||
|
{
|
||||||
|
if (accbits < exp) break;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (acc <= 0) break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
while (1);
|
||||||
|
}
|
||||||
|
|
||||||
|
STIX_ASSERT (xpos >= 1);
|
||||||
|
if (STIX_OBJ_GET_CLASS(num) == stix->_large_negative_integer) xbuf[--xpos] = '-';
|
||||||
|
|
||||||
|
s = stix_makestring (stix, &xbuf[xpos], xlen - xpos);
|
||||||
|
stix_freemem (stix, xbuf);
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Do it in a hard way for other cases */
|
||||||
/* TODO: migrate these buffers into stix_t? */
|
/* TODO: migrate these buffers into stix_t? */
|
||||||
/* TODO: find an optimial buffer size */
|
/* TODO: find an optimial buffer size */
|
||||||
xbuf = (stix_ooch_t*)stix_allocmem (stix, STIX_SIZEOF(*xbuf) * (as * STIX_LIW_BITS + 1));
|
xbuf = (stix_ooch_t*)stix_allocmem (stix, STIX_SIZEOF(*xbuf) * (as * STIX_LIW_BITS + 1));
|
||||||
@ -2474,6 +2666,17 @@ stix_oop_t stix_inttostr (stix_t* stix, stix_oop_t num, int radix)
|
|||||||
return STIX_NULL;
|
return STIX_NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if (STIX_LIW_BITS == STIX_OOW_BITS)
|
||||||
|
b[0] = stix->bigint[radix].multiplier; /* block divisor */
|
||||||
|
bs = 1;
|
||||||
|
#elif (STIX_LIW_BITS == STIX_OOHW_BITS)
|
||||||
|
b[0] = stix->bigint[radix].multiplier & STIX_LBMASK(stix_oow_t, STIX_OOHW_BITS);
|
||||||
|
b[1] = stix->bigint[radix].multiplier >> STIX_OOHW_BITS;
|
||||||
|
bs = (b[1] > 0)? 2: 1;
|
||||||
|
#else
|
||||||
|
# error UNSUPPORTED LIW BIT SIZE
|
||||||
|
#endif
|
||||||
|
|
||||||
a = &t[0];
|
a = &t[0];
|
||||||
q = &t[as];
|
q = &t[as];
|
||||||
r = &t[as * 2];
|
r = &t[as * 2];
|
||||||
|
@ -1256,6 +1256,23 @@ static int prim_integer_bitinv (stix_t* stix, stix_ooi_t nargs)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int prim_integer_bitshift (stix_t* stix, stix_ooi_t nargs)
|
||||||
|
{
|
||||||
|
stix_oop_t rcv, arg, res;
|
||||||
|
|
||||||
|
STIX_ASSERT (nargs == 1);
|
||||||
|
|
||||||
|
rcv = ACTIVE_STACK_GET(stix, stix->sp - 1);
|
||||||
|
arg = ACTIVE_STACK_GET(stix, stix->sp);
|
||||||
|
|
||||||
|
res = stix_bitshiftint (stix, rcv, arg);
|
||||||
|
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;
|
||||||
@ -1802,6 +1819,7 @@ static prim_t primitives[] =
|
|||||||
{ 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" },
|
{ 0, prim_integer_bitinv, "_integer_bitinv" },
|
||||||
|
{ 1, prim_integer_bitshift, "_integer_bitshift" },
|
||||||
{ 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" },
|
||||||
|
@ -1129,6 +1129,12 @@ stix_oop_t stix_bitinvint (
|
|||||||
stix_oop_t x
|
stix_oop_t x
|
||||||
);
|
);
|
||||||
|
|
||||||
|
stix_oop_t stix_bitshiftint (
|
||||||
|
stix_t* stix,
|
||||||
|
stix_oop_t x,
|
||||||
|
stix_oop_t y
|
||||||
|
);
|
||||||
|
|
||||||
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,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user