finished stix_bitatint()
This commit is contained in:
parent
60b90de172
commit
649a78472b
@ -378,7 +378,19 @@ PROCESS TESTING
|
||||
((-2r1000000000000000000000000000100000000000000000000000000000000000000000000000 bitShift: 13) printStringRadix: 2) dump.
|
||||
((2r1000000000000000000000000000100000000000000000000000000000000000000000000000 bitShift: 13) printStringRadix: 2) dump.
|
||||
|
||||
((-2r10 bitAt: 1) printStringRadix: 2) dump.
|
||||
((-2r1000000000000000000000000000100000000000000000000000000000000000000000000000 bitShift: -0) printStringRadix: 2) dump.
|
||||
((-2r1000000000000000000000000000100000000000000000000000000000000000000000000000 bitShift: -1) printStringRadix: 2) dump.
|
||||
((-2r1000000000000000000000000000100000000000000000000000000000000000000000000000 bitShift: -73) printStringRadix: 2) dump.
|
||||
((-2r1000000000000000000000000000100000000000000000000000000000000000000000000000 bitShift: -74) printStringRadix: 2) dump.
|
||||
((-2r1000000000000000000000000000100000000000000000000000000000000000000000000000 bitShift: -75) printStringRadix: 2) dump.
|
||||
((-2r1000000000000000000000000000100000000000000000000000000000000000000000000000 bitShift: -76) printStringRadix: 2) dump.
|
||||
((-2r1000000000000000000000000000100000000000000000000000000000000000000000000000 bitShift: -77) printStringRadix: 2) dump.
|
||||
|
||||
|
||||
(2305843009213693951 bitAt: 62) dump.
|
||||
(-2305843009213693951 bitAt: 63) dump.
|
||||
(2r1000000000000000000000000000100000000000000000000000000000000000000000000000 bitAt: 129) dump.
|
||||
(2r1000000000000000000000000000100000000000000000000000000000000000000000000000 bitAt: 16rFFFFFFFFFFFFFFFF1) dump.
|
||||
|
||||
"
|
||||
FFI isNil dump.
|
||||
|
@ -883,7 +883,7 @@ static void divide_unsigned_array (
|
||||
for (i = xs; i > 0; )
|
||||
{
|
||||
--i;
|
||||
for (j = STIX_SIZEOF(stix_liw_t) * 8; j > 0;)
|
||||
for (j = STIX_LIW_BITS; j > 0;)
|
||||
{
|
||||
--j;
|
||||
|
||||
@ -1590,6 +1590,8 @@ oops_einval:
|
||||
|
||||
stix_oop_t stix_bitatint (stix_t* stix, stix_oop_t x, stix_oop_t y)
|
||||
{
|
||||
/* y is 1-based */
|
||||
|
||||
if (STIX_OOP_IS_SMOOI(x) && STIX_OOP_IS_SMOOI(y))
|
||||
{
|
||||
stix_ooi_t v1, v2, v3;
|
||||
@ -1600,18 +1602,152 @@ stix_oop_t stix_bitatint (stix_t* stix, stix_oop_t x, stix_oop_t y)
|
||||
if (v2 <= 0) return STIX_SMOOI_TO_OOP(0);
|
||||
if (v1 >= 0)
|
||||
{
|
||||
if (v2 >= XXXXXXXXXX) return STIX_SMOOI_TO_OOP(0);
|
||||
if (v2 >= STIX_SMOOI_BITS) return STIX_SMOOI_TO_OOP(0);
|
||||
v3 = ((stix_oow_t)v1 >> (v2 - 1)) & 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (v2 >= XXXXXXXXXX) return STIX_SMOOI_TO_OOP(-1);
|
||||
if (v2 >= STIX_SMOOI_BITS) return STIX_SMOOI_TO_OOP(1);
|
||||
v3 = ((~(stix_oow_t)-v1 + 1) >> (v2 - 1)) & 1;
|
||||
}
|
||||
return STIX_SMOOI_TO_OOP(v3);
|
||||
}
|
||||
else if (STIX_OOP_IS_SMOOI(x))
|
||||
{
|
||||
if (!is_integer(stix, y)) goto oops_einval;
|
||||
|
||||
if (STIX_OBJ_GET_CLASS(y) == stix->_large_negative_integer) return STIX_SMOOI_TO_OOP(0);
|
||||
/* y is definitely >= STIX_SMOOI_BITS */
|
||||
if (STIX_OOP_TO_SMOOI(x) >= 0)
|
||||
return STIX_SMOOI_TO_OOP(0);
|
||||
else
|
||||
return STIX_SMOOI_TO_OOP(1);
|
||||
}
|
||||
else if (STIX_OOP_IS_SMOOI(y))
|
||||
{
|
||||
stix_ooi_t v;
|
||||
stix_oow_t wp, bp, xs;
|
||||
|
||||
if (!is_integer(stix, x)) goto oops_einval;
|
||||
v = STIX_OOP_TO_SMOOI(y);
|
||||
|
||||
if (v <= 0) return STIX_SMOOI_TO_OOP(0);
|
||||
wp = (v - 1) / STIX_LIW_BITS;
|
||||
bp = (v - 1) - (wp * STIX_LIW_BITS);
|
||||
|
||||
xs = STIX_OBJ_GET_SIZE(x);
|
||||
if (STIX_OBJ_GET_CLASS(x) == stix->_large_positive_integer)
|
||||
{
|
||||
if (wp >= xs) return STIX_SMOOI_TO_OOP(0);
|
||||
v = (((stix_oop_liword_t)x)->slot[wp] >> bp) & 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
stix_lidw_t w, carry;
|
||||
stix_oow_t i;
|
||||
|
||||
if (wp >= xs) return STIX_SMOOI_TO_OOP(1);
|
||||
|
||||
carry = 1;
|
||||
for (i = 0; i <= wp; i++)
|
||||
{
|
||||
w = (stix_lidw_t)((stix_liw_t)~((stix_oop_liword_t)x)->slot[i]) + carry;
|
||||
carry = w >> STIX_LIW_BITS;
|
||||
}
|
||||
v = ((stix_oow_t)w >> bp) & 1;
|
||||
}
|
||||
|
||||
return STIX_SMOOI_TO_OOP(v);
|
||||
}
|
||||
else
|
||||
{
|
||||
#if defined(STIX_LIMIT_OBJ_SIZE)
|
||||
/* nothing */
|
||||
#else
|
||||
stix_oow_t w, wp, bp, xs;
|
||||
stix_ooi_t v;
|
||||
int sign;
|
||||
#endif
|
||||
|
||||
if (!is_integer(stix, x) || !is_integer(stix, y)) goto oops_einval;
|
||||
|
||||
#if defined(STIX_LIMIT_OBJ_SIZE)
|
||||
if (STIX_OBJ_GET_CLASS(y) == stix->_large_negative_integer) return STIX_SMOOI_TO_OOP(0);
|
||||
|
||||
STIX_ASSERT (STIX_OBJ_SIZE_BITS_MAX <= STIX_TYPE_MAX(stix_oow_t));
|
||||
if (STIX_OBJ_GET_CLASS(x) == stix->_large_positive_integer)
|
||||
{
|
||||
return STIX_SMOOI_TO_OOP (0);
|
||||
}
|
||||
else
|
||||
{
|
||||
return STIX_SMOOI_TO_OOP (1);
|
||||
}
|
||||
#else
|
||||
xs = STIX_OBJ_GET_SIZE(x);
|
||||
|
||||
if (STIX_OBJ_GET_CLASS(y) == stix->_large_negative_integer) return STIX_SMOOI_TO_OOP(0);
|
||||
|
||||
sign = integer_to_oow (stix, y, &w);
|
||||
STIX_ASSERT (sign >= 0);
|
||||
if (sign >= 1)
|
||||
{
|
||||
wp = (w - 1) / STIX_LIW_BITS;
|
||||
bp = (w - 1) - (wp * STIX_LIW_BITS);
|
||||
}
|
||||
else
|
||||
{
|
||||
stix_oop_t quo, rem;
|
||||
|
||||
STIX_ASSERT (sign == 0);
|
||||
|
||||
stix_pushtmp (stix, &x);
|
||||
y = stix_subints (stix, y, STIX_SMOOI_TO_OOP(1));
|
||||
stix_poptmp (stix);
|
||||
if (!y) return STIX_NULL;
|
||||
|
||||
stix_pushtmp (stix, &x);
|
||||
quo = stix_divints (stix, y, STIX_SMOOI_TO_OOP(STIX_LIW_BITS), 0, &rem);
|
||||
stix_poptmp (stix);
|
||||
if (!quo) return STIX_NULL;
|
||||
|
||||
sign = integer_to_oow (stix, quo, &wp);
|
||||
STIX_ASSERT (sign >= 0);
|
||||
if (sign == 0)
|
||||
{
|
||||
/* too large. set it to xs so that it gets out of
|
||||
* the valid range */
|
||||
wp = xs;
|
||||
}
|
||||
|
||||
STIX_ASSERT (STIX_OOP_IS_SMOOI(rem));
|
||||
bp = STIX_OOP_TO_SMOOI(rem);
|
||||
STIX_ASSERT (bp >= 0 && bp < STIX_LIW_BITS);
|
||||
}
|
||||
|
||||
if (STIX_OBJ_GET_CLASS(x) == stix->_large_positive_integer)
|
||||
{
|
||||
if (wp >= xs) return STIX_SMOOI_TO_OOP(0);
|
||||
v = (((stix_oop_liword_t)x)->slot[wp] >> bp) & 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
stix_lidw_t w, carry;
|
||||
stix_oow_t i;
|
||||
|
||||
if (wp >= xs) return STIX_SMOOI_TO_OOP(1);
|
||||
|
||||
carry = 1;
|
||||
for (i = 0; i <= wp; i++)
|
||||
{
|
||||
w = (stix_lidw_t)((stix_liw_t)~((stix_oop_liword_t)x)->slot[i]) + carry;
|
||||
carry = w >> STIX_LIW_BITS;
|
||||
}
|
||||
v = ((stix_oow_t)w >> bp) & 1;
|
||||
}
|
||||
|
||||
return STIX_SMOOI_TO_OOP(v);
|
||||
#endif
|
||||
}
|
||||
|
||||
oops_einval:
|
||||
@ -2773,7 +2909,7 @@ stix_oop_t stix_bitshiftint (stix_t* stix, stix_oop_t x, stix_oop_t y)
|
||||
/* the maximum number of bit shifts are guaranteed to be
|
||||
* small enough to fit into the stix_oow_t type. so i can
|
||||
* easily assume that all bits are shifted out */
|
||||
STIX_ASSERT (STIX_TYPE_MAX(stix_oow_t) >= STIX_OBJ_SIZE_MAX * 8);
|
||||
STIX_ASSERT (STIX_OBJ_SIZE_BITS_MAX <= STIX_TYPE_MAX(stix_oow_t));
|
||||
return (negx)? STIX_SMOOI_TO_OOP(-1): STIX_SMOOI_TO_OOP(0);
|
||||
#else
|
||||
if (negx)
|
||||
@ -2790,7 +2926,7 @@ stix_oop_t stix_bitshiftint (stix_t* stix, stix_oop_t x, stix_oop_t y)
|
||||
* small enough to fit into the stix_oow_t type. so i can
|
||||
* simply return a failure here becuase it's surely too
|
||||
* large after shifting */
|
||||
STIX_ASSERT (STIX_TYPE_MAX(stix_oow_t) >= STIX_OBJ_SIZE_MAX * 8);
|
||||
STIX_ASSERT (STIX_TYPE_MAX(stix_oow_t) >= STIX_OBJ_SIZE_BITS_MAX);
|
||||
stix->errnum = STIX_EOOMEM; /* is it a soft failure or a hard failure? is this error code proper? */
|
||||
return STIX_NULL;
|
||||
#else
|
||||
|
@ -222,8 +222,10 @@
|
||||
* 2. the maximum number of bit shifts can be represented in the stix_oow_t type.
|
||||
*/
|
||||
# define STIX_OBJ_SIZE_MAX ((stix_oow_t)STIX_SMOOI_MAX)
|
||||
# define STIX_OBJ_SIZE_BITS_MAX (STIX_OBJ_SIZE_MAX * 8)
|
||||
#else
|
||||
# define STIX_OBJ_SIZE_MAX ((stix_oow_t)STIX_TYPE_MAX(stix_oow_t))
|
||||
# define STIX_OBJ_SIZE_BITS_MAX (STIX_OBJ_SIZE_MAX * 8)
|
||||
#endif
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user