added moo_sqrtint() and moo_absint()
This commit is contained in:
parent
838189c438
commit
cf5c9d0461
110
moo/lib/bigint.c
110
moo/lib/bigint.c
@ -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;
|
||||||
|
@ -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,
|
||||||
|
@ -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
|
||||||
* ========================================================================= */
|
* ========================================================================= */
|
||||||
|
Loading…
Reference in New Issue
Block a user