finished stix_bitatint()

This commit is contained in:
hyunghwan.chung 2015-12-26 05:11:10 +00:00
parent 60b90de172
commit 649a78472b
3 changed files with 156 additions and 6 deletions

View File

@ -378,7 +378,19 @@ PROCESS TESTING
((-2r1000000000000000000000000000100000000000000000000000000000000000000000000000 bitShift: 13) printStringRadix: 2) dump. ((-2r1000000000000000000000000000100000000000000000000000000000000000000000000000 bitShift: 13) printStringRadix: 2) dump.
((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. FFI isNil dump.

View File

@ -883,7 +883,7 @@ static void divide_unsigned_array (
for (i = xs; i > 0; ) for (i = xs; i > 0; )
{ {
--i; --i;
for (j = STIX_SIZEOF(stix_liw_t) * 8; j > 0;) for (j = STIX_LIW_BITS; j > 0;)
{ {
--j; --j;
@ -1590,6 +1590,8 @@ oops_einval:
stix_oop_t stix_bitatint (stix_t* stix, stix_oop_t x, stix_oop_t y) 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)) if (STIX_OOP_IS_SMOOI(x) && STIX_OOP_IS_SMOOI(y))
{ {
stix_ooi_t v1, v2, v3; 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 (v2 <= 0) return STIX_SMOOI_TO_OOP(0);
if (v1 >= 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; v3 = ((stix_oow_t)v1 >> (v2 - 1)) & 1;
} }
else 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; v3 = ((~(stix_oow_t)-v1 + 1) >> (v2 - 1)) & 1;
} }
return STIX_SMOOI_TO_OOP(v3); 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 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: 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 /* the maximum number of bit shifts are guaranteed to be
* small enough to fit into the stix_oow_t type. so i can * small enough to fit into the stix_oow_t type. so i can
* easily assume that all bits are shifted out */ * 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); return (negx)? STIX_SMOOI_TO_OOP(-1): STIX_SMOOI_TO_OOP(0);
#else #else
if (negx) 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 * small enough to fit into the stix_oow_t type. so i can
* simply return a failure here becuase it's surely too * simply return a failure here becuase it's surely too
* large after shifting */ * 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? */ stix->errnum = STIX_EOOMEM; /* is it a soft failure or a hard failure? is this error code proper? */
return STIX_NULL; return STIX_NULL;
#else #else

View File

@ -222,8 +222,10 @@
* 2. the maximum number of bit shifts can be represented in the stix_oow_t type. * 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_MAX ((stix_oow_t)STIX_SMOOI_MAX)
# define STIX_OBJ_SIZE_BITS_MAX (STIX_OBJ_SIZE_MAX * 8)
#else #else
# define STIX_OBJ_SIZE_MAX ((stix_oow_t)STIX_TYPE_MAX(stix_oow_t)) # 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 #endif