added moo_sqrtint() and moo_absint()

This commit is contained in:
hyunghwan.chung 2018-04-07 06:29:17 +00:00
parent 838189c438
commit cf5c9d0461
3 changed files with 127 additions and 6 deletions

View File

@ -4001,6 +4001,116 @@ oops_einval:
return MOO_NULL; return MOO_NULL;
} }
moo_oop_t moo_sqrtint (moo_t* moo, moo_oop_t x)
{
/* TODO: find a faster and more efficient algorithm??? */
moo_oop_t a, b, m, m2, t;
int neg;
if (!moo_isint(moo, x))
{
moo_seterrbfmt (moo, MOO_EINVAL, "parameter not integer - %O", x);
return MOO_NULL;
}
a = moo->_nil;
b = moo->_nil;
m = moo->_nil;
m2 = moo->_nil;
moo_pushtmp (moo, &x);
moo_pushtmp (moo, &a);
moo_pushtmp (moo, &b);
moo_pushtmp (moo, &m);
moo_pushtmp (moo, &m2);
a = moo_ltints(moo, x, MOO_SMOOI_TO_OOP(0));
if (!a) goto oops;
if (a == moo->_true)
{
/* the given number is a negative number.
* i will arrange the return value to be negative. */
x = moo_negateint(moo, x);
if (!x) goto oops;
neg = 1;
}
else neg = 0;
a = MOO_SMOOI_TO_OOP(1);
b = moo_bitshiftint(moo, x, MOO_SMOOI_TO_OOP(-5));
if (!b) goto oops;
b = moo_addints(moo, b, MOO_SMOOI_TO_OOP(8));
if (!b) goto oops;
while (1)
{
t = moo_geints(moo, b, a);
if (!t) return MOO_NULL;
if (t == moo->_false) break;
m = moo_addints(moo, a, b);
if (!m) goto oops;
m = moo_bitshiftint(moo, m, MOO_SMOOI_TO_OOP(-1));
if (!m) goto oops;
m2 = moo_mulints(moo, m, m);
if (!m2) goto oops;
t = moo_gtints(moo, m2, x);
if (!t) return MOO_NULL;
if (t == moo->_true)
{
b = moo_subints(moo, m, MOO_SMOOI_TO_OOP(1));
if (!b) goto oops;
}
else
{
a = moo_addints(moo, m, MOO_SMOOI_TO_OOP(1));
if (!a) goto oops;
}
}
moo_poptmps (moo, 5);
x = moo_subints(moo, a, MOO_SMOOI_TO_OOP(1));
if (!x) return MOO_NULL;
if (neg) x = moo_negateint(moo, x);
return x;
oops:
moo_poptmps (moo, 5);
return MOO_NULL;
}
moo_oop_t moo_absint (moo_t* moo, moo_oop_t x)
{
if (MOO_OOP_IS_SMOOI(x))
{
moo_ooi_t v;
v = MOO_OOP_TO_SMOOI(x);
if (v < 0)
{
v = -v;
x = MOO_SMOOI_TO_OOP(v);
}
}
else if (IS_NBIGINT(moo, x))
{
x = _clone_bigint(moo, x, MOO_OBJ_GET_SIZE(x), moo->_large_positive_integer);
}
else if (IS_PBIGINT(moo, x))
{
/* do nothing. return x without change.
* [THINK] but do i need to clone a positive bigint? */
}
else
{
moo_seterrbfmt (moo, MOO_EINVAL, "parameter not integer - %O", x);
return MOO_NULL;
}
return x;
}
moo_oop_t moo_inttostr (moo_t* moo, moo_oop_t num, int radix) moo_oop_t moo_inttostr (moo_t* moo, moo_oop_t num, int radix)
{ {
moo_ooi_t v = 0; moo_ooi_t v = 0;

View File

@ -1310,6 +1310,16 @@ moo_oop_t moo_leints (
moo_oop_t y moo_oop_t y
); );
moo_oop_t moo_sqrtint (
moo_t* moo,
moo_oop_t x
);
moo_oop_t moo_absint (
moo_t* moo,
moo_oop_t x
);
moo_oop_t moo_strtoint ( moo_oop_t moo_strtoint (
moo_t* moo, moo_t* moo,
const moo_ooch_t* str, const moo_ooch_t* str,

View File

@ -1625,12 +1625,6 @@ typedef struct moo_synerr_t moo_synerr_t;
extern "C" { extern "C" {
#endif #endif
#if defined(MOO_HAVE_INLINE)
static MOO_INLINE void moo_switchprocess(moo_t* moo) { moo->switch_proc = 1; }
#else
# define moo_switchprocess(moo) ((moo)->switch_proc = 1)
#endif
MOO_EXPORT moo_t* moo_open ( MOO_EXPORT moo_t* moo_open (
moo_mmgr_t* mmgr, moo_mmgr_t* mmgr,
moo_oow_t xtnsize, moo_oow_t xtnsize,
@ -1820,6 +1814,13 @@ MOO_EXPORT void moo_abort (
moo_t* moo moo_t* moo
); );
#if defined(MOO_HAVE_INLINE)
static MOO_INLINE void moo_switchprocess(moo_t* moo) { moo->switch_proc = 1; }
#else
# define moo_switchprocess(moo) ((moo)->switch_proc = 1)
#endif
/* ========================================================================= /* =========================================================================
* COMMON OBJECT MANAGEMENT FUNCTIONS * COMMON OBJECT MANAGEMENT FUNCTIONS
* ========================================================================= */ * ========================================================================= */