added moo_inttouintmax and moo_inttointmax
This commit is contained in:
parent
99bca6a028
commit
3f2e39cf44
117
moo/lib/bigint.c
117
moo/lib/bigint.c
@ -374,7 +374,7 @@ int moo_inttoooi (moo_t* moo, moo_oop_t x, moo_ooi_t* i)
|
||||
n = moo_inttooow(moo, x, &w);
|
||||
if (n < 0)
|
||||
{
|
||||
MOO_ASSERT (moo, MOO_TYPE_MAX(moo_ooi_t) + MOO_TYPE_MIN(moo_ooi_t) == -1); /* assume 2's complement */
|
||||
MOO_STATIC_ASSERT (MOO_TYPE_MAX(moo_ooi_t) + MOO_TYPE_MIN(moo_ooi_t) == -1); /* assume 2's complement */
|
||||
if (w > (moo_oow_t)MOO_TYPE_MAX(moo_ooi_t) + 1)
|
||||
{
|
||||
moo_seterrnum (moo, MOO_ERANGE); /* not convertable. number too small */
|
||||
@ -395,6 +395,121 @@ int moo_inttoooi (moo_t* moo, moo_oop_t x, moo_ooi_t* i)
|
||||
return n;
|
||||
}
|
||||
|
||||
#if (MOO_SIZEOF_UINTMAX_T == MOO_SIZEOF_OOW_T)
|
||||
|
||||
/* do nothing. required macros are defined in moo.h */
|
||||
|
||||
#elif (MOO_SIZEOF_UINTMAX_T == MOO_SIZEOF_OOW_T * 2)
|
||||
static MOO_INLINE int bigint_to_uintmax (moo_t* moo, moo_oop_t num, moo_uintmax_t* w)
|
||||
{
|
||||
MOO_ASSERT (moo, MOO_OOP_IS_POINTER(num));
|
||||
MOO_ASSERT (moo, MOO_POINTER_IS_PBIGINT(moo, num) || MOO_POINTER_IS_NBIGINT(moo, num));
|
||||
|
||||
#if (MOO_LIW_BITS == MOO_OOW_BITS)
|
||||
MOO_ASSERT (moo, MOO_OBJ_GET_SIZE(num) >= 1);
|
||||
|
||||
switch (MOO_OBJ_GET_SIZE(num))
|
||||
{
|
||||
case 1:
|
||||
*w = ((moo_uintmax_t)MOO_OBJ_GET_WORD_SLOT(num)[0];
|
||||
goto done;
|
||||
|
||||
case 2:
|
||||
*w = ((moo_uintmax_t)MOO_OBJ_GET_WORD_SLOT(num)[0] << MOO_LIW_BITS) | MOO_OBJ_GET_WORD_SLOT(num)[1];
|
||||
goto done;
|
||||
|
||||
default:
|
||||
goto oops_range;
|
||||
}
|
||||
|
||||
#elif (MOO_LIW_BITS == MOO_OOHW_BITS)
|
||||
MOO_ASSERT (moo, MOO_OBJ_GET_SIZE(num) >= 2);
|
||||
switch (MOO_OBJ_GET_SIZE(num))
|
||||
{
|
||||
case 2:
|
||||
*w = ((moo_uintmax_t)MOO_OBJ_GET_HALFWORD_SLOT(num)[0] << MOO_LIW_BITS) | MOO_OBJ_GET_HALFWORD_SLOT(num)[1];
|
||||
goto done;
|
||||
|
||||
case 4:
|
||||
*w = ((moo_uintmax_t)MOO_OBJ_GET_HALFWORD_SLOT(num)[0] << MOO_LIW_BITS * 3) |
|
||||
((moo_uintmax_t)MOO_OBJ_GET_HALFWORD_SLOT(num)[1] << MOO_LIW_BITS * 2) |
|
||||
((moo_uintmax_t)MOO_OBJ_GET_HALFWORD_SLOT(num)[2] << MOO_LIW_BITS * 1) |
|
||||
MOO_OBJ_GET_HALFWORD_SLOT(num)[3];
|
||||
goto done;
|
||||
|
||||
default:
|
||||
goto oops_range;
|
||||
}
|
||||
#else
|
||||
# error UNSUPPORTED LIW BIT SIZE
|
||||
#endif
|
||||
|
||||
done:
|
||||
return (MOO_POINTER_IS_NBIGINT(moo, num))? -1: 1;
|
||||
|
||||
oops_range:
|
||||
moo_seterrnum (moo, MOO_ERANGE);
|
||||
return 0; /* not convertable */
|
||||
}
|
||||
|
||||
int moo_inttouintmax (moo_t* moo, moo_oop_t x, moo_uintmax_t* w)
|
||||
{
|
||||
if (MOO_OOP_IS_SMOOI(x))
|
||||
{
|
||||
moo_ooi_t v;
|
||||
|
||||
v = MOO_OOP_TO_SMOOI(x);
|
||||
if (v < 0)
|
||||
{
|
||||
*w = -v;
|
||||
return -1; /* negative number negated - kind of an error */
|
||||
}
|
||||
else
|
||||
{
|
||||
*w = v;
|
||||
return 1; /* zero or positive number */
|
||||
}
|
||||
}
|
||||
|
||||
if (moo_isbigint(moo, x)) return bigint_to_uintmax(moo, x, w);
|
||||
|
||||
moo_seterrbfmt (moo, MOO_EINVAL, "not an integer - %O", x);
|
||||
return 0; /* not convertable - too big, too small, or not an integer */
|
||||
}
|
||||
|
||||
int moo_inttointmax (moo_t* moo, moo_oop_t x, moo_intmax_t* i)
|
||||
{
|
||||
moo_uintmax_t w;
|
||||
int n;
|
||||
|
||||
n = moo_inttouintmax(moo, x, &w);
|
||||
if (n < 0)
|
||||
{
|
||||
MOO_STATIC_ASSERT (MOO_TYPE_MAX(moo_intmax_t) + MOO_TYPE_MIN(moo_intmax_t) == -1); /* assume 2's complement */
|
||||
if (w > (moo_uintmax_t)MOO_TYPE_MAX(moo_intmax_t) + 1)
|
||||
{
|
||||
moo_seterrnum (moo, MOO_ERANGE); /* not convertable. number too small */
|
||||
return 0;
|
||||
}
|
||||
*i = -w;
|
||||
}
|
||||
else if (n > 0)
|
||||
{
|
||||
if (w > MOO_TYPE_MAX(moo_intmax_t))
|
||||
{
|
||||
moo_seterrnum (moo, MOO_ERANGE); /* not convertable. number too big */
|
||||
return 0;
|
||||
}
|
||||
*i = w;
|
||||
}
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
#else
|
||||
# error UNSUPPORTED UINTMAX SIZE
|
||||
#endif
|
||||
|
||||
static MOO_INLINE moo_oop_t make_bigint_with_oow (moo_t* moo, moo_oow_t w)
|
||||
{
|
||||
#if (MOO_LIW_BITS == MOO_OOW_BITS)
|
||||
|
@ -2208,6 +2208,23 @@ MOO_EXPORT int moo_inttoooi (
|
||||
moo_ooi_t* i
|
||||
);
|
||||
|
||||
#if (MOO_SIZEOF_UINTMAX_T == MOO_SIZEOF_OOW_T)
|
||||
# define moo_inttouintmax moo_inttooow
|
||||
# define moo_inttointmax moo_inttoooi
|
||||
#else
|
||||
MOO_EXPORT int moo_inttouintmax (
|
||||
moo_t* moo,
|
||||
moo_oop_t x,
|
||||
moo_uintmax_t* w
|
||||
);
|
||||
|
||||
MOO_EXPORT int moo_inttointmax (
|
||||
moo_t* moo,
|
||||
moo_oop_t x,
|
||||
moo_intmax_t* i
|
||||
);
|
||||
#endif
|
||||
|
||||
MOO_EXPORT moo_oop_t moo_findclass (
|
||||
moo_t* moo,
|
||||
moo_oop_nsdic_t nsdic,
|
||||
|
Loading…
x
Reference in New Issue
Block a user