added doWithIndex:. from:to:do: from:to:doWithIndex: to SequenceableCollection
added scale and scale: to Integer and FixedPointDecimal added moo_truncfpdec()
This commit is contained in:
@ -2027,7 +2027,7 @@ moo_oop_t moo_divints (moo_t* moo, moo_oop_t x, moo_oop_t y, int modulo, moo_oop
|
||||
}
|
||||
|
||||
moo_pushvolat (moo, &y);
|
||||
x = make_bigint_with_ooi (moo, v);
|
||||
x = make_bigint_with_ooi(moo, v);
|
||||
moo_popvolat (moo);
|
||||
if (!x) return MOO_NULL;
|
||||
}
|
||||
@ -2045,14 +2045,14 @@ moo_oop_t moo_divints (moo_t* moo, moo_oop_t x, moo_oop_t y, int modulo, moo_oop
|
||||
return MOO_NULL;
|
||||
|
||||
case 1:
|
||||
z = clone_bigint (moo, x, MOO_OBJ_GET_SIZE(x));
|
||||
z = clone_bigint(moo, x, MOO_OBJ_GET_SIZE(x));
|
||||
if (!z) return MOO_NULL;
|
||||
if (rem) *rem = MOO_SMOOI_TO_OOP(0);
|
||||
return z;
|
||||
|
||||
|
||||
case -1:
|
||||
z = clone_bigint_negated (moo, x, MOO_OBJ_GET_SIZE(x));
|
||||
z = clone_bigint_negated(moo, x, MOO_OBJ_GET_SIZE(x));
|
||||
if (!z) return MOO_NULL;
|
||||
if (rem) *rem = MOO_SMOOI_TO_OOP(0);
|
||||
return z;
|
||||
@ -2072,7 +2072,7 @@ moo_oop_t moo_divints (moo_t* moo, moo_oop_t x, moo_oop_t y, int modulo, moo_oop
|
||||
}
|
||||
|
||||
moo_pushvolat (moo, &x);
|
||||
y = make_bigint_with_ooi (moo, v);
|
||||
y = make_bigint_with_ooi(moo, v);
|
||||
moo_popvolat (moo);
|
||||
if (!y) return MOO_NULL;
|
||||
}
|
||||
@ -2088,7 +2088,7 @@ moo_oop_t moo_divints (moo_t* moo, moo_oop_t x, moo_oop_t y, int modulo, moo_oop
|
||||
|
||||
moo_pushvolat (moo, &x);
|
||||
moo_pushvolat (moo, &y);
|
||||
z = divide_unsigned_integers (moo, x, y, &r);
|
||||
z = divide_unsigned_integers(moo, x, y, &r);
|
||||
moo_popvolats (moo, 2);
|
||||
if (!z) return MOO_NULL;
|
||||
|
||||
@ -2115,17 +2115,17 @@ moo_oop_t moo_divints (moo_t* moo, moo_oop_t x, moo_oop_t y, int modulo, moo_oop
|
||||
{
|
||||
moo_pushvolat (moo, &z);
|
||||
moo_pushvolat (moo, &y);
|
||||
r = moo_addints (moo, r, y);
|
||||
r = moo_addints(moo, r, y);
|
||||
moo_popvolats (moo, 2);
|
||||
if (!r) return MOO_NULL;
|
||||
|
||||
moo_pushvolat (moo, &r);
|
||||
z = normalize_bigint (moo, z);
|
||||
z = normalize_bigint(moo, z);
|
||||
moo_popvolat (moo);
|
||||
if (!z) return MOO_NULL;
|
||||
|
||||
moo_pushvolat (moo, &r);
|
||||
z = moo_subints (moo, z, MOO_SMOOI_TO_OOP(1));
|
||||
z = moo_subints(moo, z, MOO_SMOOI_TO_OOP(1));
|
||||
moo_popvolat (moo);
|
||||
if (!z) return MOO_NULL;
|
||||
|
||||
@ -2138,20 +2138,20 @@ moo_oop_t moo_divints (moo_t* moo, moo_oop_t x, moo_oop_t y, int modulo, moo_oop
|
||||
/* TODO: subtract 1 without normalization??? */
|
||||
z = normalize_bigint (moo, z);
|
||||
if (!z) return MOO_NULL;
|
||||
return moo_subints (moo, z, MOO_SMOOI_TO_OOP(1));
|
||||
return moo_subints(moo, z, MOO_SMOOI_TO_OOP(1));
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
moo_pushvolat (moo, &z);
|
||||
r = normalize_bigint (moo, r);
|
||||
r = normalize_bigint(moo, r);
|
||||
moo_popvolat (moo);
|
||||
if (!r) return MOO_NULL;
|
||||
}
|
||||
|
||||
if (rem) *rem = r;
|
||||
return normalize_bigint (moo, z);
|
||||
return normalize_bigint(moo, z);
|
||||
|
||||
oops_einval:
|
||||
moo_seterrbfmt (moo, MOO_EINVAL, "invalid parameters - %O, %O", x, y);
|
||||
|
@ -2820,6 +2820,27 @@ static moo_pfrc_t pf_system_return_value_to_context (moo_t* moo, moo_mod_t* mod,
|
||||
return MOO_PF_SUCCESS;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------ */
|
||||
static moo_pfrc_t pf_number_scale (moo_t* moo, moo_mod_t* mod, moo_ooi_t nargs)
|
||||
{
|
||||
moo_oop_t rcv, arg, res;
|
||||
|
||||
rcv = MOO_STACK_GETRCV(moo, nargs);
|
||||
arg = MOO_STACK_GETARG(moo, nargs, 0);
|
||||
|
||||
if (!MOO_OOP_IS_SMOOI(arg))
|
||||
{
|
||||
moo_seterrbfmt (moo, MOO_EINVAL, "invalid scale - %O", arg);
|
||||
return MOO_PF_FAILURE;
|
||||
}
|
||||
|
||||
res = moo_truncfpdec(moo, rcv, MOO_OOP_TO_SMOOI(arg));
|
||||
if (!res) return (moo->errnum == MOO_EINVAL? MOO_PF_FAILURE: MOO_PF_HARD_FAILURE);
|
||||
|
||||
MOO_STACK_SETRET (moo, nargs, res);
|
||||
return MOO_PF_SUCCESS;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------ */
|
||||
|
||||
static moo_pfrc_t pf_number_add (moo_t* moo, moo_mod_t* mod, moo_ooi_t nargs)
|
||||
@ -3779,7 +3800,32 @@ static pf_t pftab[] =
|
||||
{ "Error_asInteger", { pf_error_as_integer, 0, 0 } },
|
||||
{ "Error_asString", { pf_error_as_string, 0, 0 } },
|
||||
|
||||
{ "MethodContext_goto:", { pf_context_goto, 1, 1 } },
|
||||
{ "FixedPointDecimal_scale:", { pf_number_scale, 1, 1 } },
|
||||
|
||||
{ "Integer_add", { pf_integer_add, 1, 1 } },
|
||||
{ "Integer_bitand", { pf_integer_bitand, 1, 1 } },
|
||||
{ "Integer_bitat", { pf_integer_bitat, 1, 1 } },
|
||||
{ "Integer_bitinv", { pf_integer_bitinv, 0, 0 } },
|
||||
{ "Integer_bitor", { pf_integer_bitor, 1, 1 } },
|
||||
{ "Integer_bitshift", { pf_integer_bitshift, 1, 1 } },
|
||||
{ "Integer_bitxor", { pf_integer_bitxor, 1, 1 } },
|
||||
{ "Integer_div", { pf_integer_div, 1, 1 } },
|
||||
{ "Integer_eq", { pf_integer_eq, 1, 1 } },
|
||||
{ "Integer_ge", { pf_integer_ge, 1, 1 } },
|
||||
{ "Integer_gt", { pf_integer_gt, 1, 1 } },
|
||||
{ "Integer_inttostr", { pf_integer_inttostr, 1, 1 } },
|
||||
{ "Integer_le", { pf_integer_le, 1, 1 } },
|
||||
{ "Integer_lt", { pf_integer_lt, 1, 1 } },
|
||||
{ "Integer_mdiv", { pf_integer_mdiv, 1, 1 } },
|
||||
{ "Integer_mod", { pf_integer_mod, 1, 1 } },
|
||||
{ "Integer_mul", { pf_integer_mul, 1, 1 } },
|
||||
{ "Integer_ne", { pf_integer_ne, 1, 1 } },
|
||||
{ "Integer_negated", { pf_integer_negated, 0, 0 } },
|
||||
{ "Integer_rem", { pf_integer_rem, 1, 1 } },
|
||||
{ "Integer_scale:", { pf_number_scale, 1, 1 } },
|
||||
{ "Integer_sub", { pf_integer_sub, 1, 1 } },
|
||||
|
||||
{ "MethodContext_goto:", { pf_context_goto, 1, 1 } },
|
||||
|
||||
{ "Process_resume", { pf_process_resume, 0, 0 } },
|
||||
{ "Process_sp", { pf_process_sp, 0, 0 } },
|
||||
@ -3859,28 +3905,6 @@ static pf_t pftab[] =
|
||||
|
||||
{ "_dump", { pf_dump, 0, MA } },
|
||||
|
||||
{ "_integer_add", { pf_integer_add, 1, 1 } },
|
||||
{ "_integer_bitand", { pf_integer_bitand, 1, 1 } },
|
||||
{ "_integer_bitat", { pf_integer_bitat, 1, 1 } },
|
||||
{ "_integer_bitinv", { pf_integer_bitinv, 0, 0 } },
|
||||
{ "_integer_bitor", { pf_integer_bitor, 1, 1 } },
|
||||
{ "_integer_bitshift", { pf_integer_bitshift, 1, 1 } },
|
||||
{ "_integer_bitxor", { pf_integer_bitxor, 1, 1 } },
|
||||
{ "_integer_div", { pf_integer_div, 1, 1 } },
|
||||
{ "_integer_eq", { pf_integer_eq, 1, 1 } },
|
||||
{ "_integer_ge", { pf_integer_ge, 1, 1 } },
|
||||
{ "_integer_gt", { pf_integer_gt, 1, 1 } },
|
||||
{ "_integer_inttostr", { pf_integer_inttostr, 1, 1 } },
|
||||
{ "_integer_le", { pf_integer_le, 1, 1 } },
|
||||
{ "_integer_lt", { pf_integer_lt, 1, 1 } },
|
||||
{ "_integer_mdiv", { pf_integer_mdiv, 1, 1 } },
|
||||
{ "_integer_mod", { pf_integer_mod, 1, 1 } },
|
||||
{ "_integer_mul", { pf_integer_mul, 1, 1 } },
|
||||
{ "_integer_ne", { pf_integer_ne, 1, 1 } },
|
||||
{ "_integer_negated", { pf_integer_negated, 0, 0 } },
|
||||
{ "_integer_rem", { pf_integer_rem, 1, 1 } },
|
||||
{ "_integer_sub", { pf_integer_sub, 1, 1 } },
|
||||
|
||||
{ "_number_add", { pf_number_add, 1, 1 } },
|
||||
{ "_number_div", { pf_number_div, 1, 1 } },
|
||||
{ "_number_eq", { pf_number_eq, 1, 1 } },
|
||||
@ -3894,6 +3918,7 @@ static pf_t pftab[] =
|
||||
{ "_number_ne", { pf_number_ne, 1, 1 } },
|
||||
{ "_number_negated", { pf_number_negated, 0, 0 } },
|
||||
{ "_number_numtostr", { pf_number_numtostr, 1, 1 } },
|
||||
{ "_number_scale:", { pf_number_scale, 1, 1 } },
|
||||
{ "_number_sub", { pf_number_sub, 1, 1 } },
|
||||
|
||||
{ "_utf8_seqlen", { moo_pf_utf8_seqlen, 0, 0 } },
|
||||
|
@ -1372,6 +1372,12 @@ moo_oop_t moo_truncfpdecval (
|
||||
moo_ooi_t ns /* new scale */
|
||||
);
|
||||
|
||||
moo_oop_t moo_truncfpdec (
|
||||
moo_t* moo,
|
||||
moo_oop_t iv, /* integer */
|
||||
moo_ooi_t ns /* new scale */
|
||||
);
|
||||
|
||||
moo_oop_t moo_addnums (
|
||||
moo_t* moo,
|
||||
moo_oop_t x,
|
||||
|
@ -121,8 +121,9 @@ static moo_ooi_t equalize_scale (moo_t* moo, moo_oop_t* x, moo_oop_t* y)
|
||||
|
||||
moo_oop_t moo_truncfpdecval (moo_t* moo, moo_oop_t iv, moo_ooi_t cs, moo_ooi_t ns)
|
||||
{
|
||||
/* this function truncates an existing fixed-point decimal.
|
||||
* it doesn't create a new object */
|
||||
/* this function truncates an existing fixed-point decimal value only if
|
||||
* the existing scale is greater than the new scale given.
|
||||
* [NOTE] this doesn't work on the fpdec object. */
|
||||
|
||||
if (cs > ns)
|
||||
{
|
||||
@ -139,6 +140,60 @@ moo_oop_t moo_truncfpdecval (moo_t* moo, moo_oop_t iv, moo_ooi_t cs, moo_ooi_t n
|
||||
return iv;
|
||||
}
|
||||
|
||||
moo_oop_t moo_truncfpdec (moo_t* moo, moo_oop_t x, moo_ooi_t ns)
|
||||
{
|
||||
moo_oop_t xv;
|
||||
moo_ooi_t cs;
|
||||
|
||||
if (MOO_OOP_IS_FPDEC(moo, x))
|
||||
{
|
||||
xv = ((moo_oop_fpdec_t)x)->value;
|
||||
cs = MOO_OOP_TO_SMOOI(((moo_oop_fpdec_t)x)->scale);
|
||||
}
|
||||
else if (moo_isint(moo, x))
|
||||
{
|
||||
/* this accepts an integer unlike the function name implies */
|
||||
xv = x;
|
||||
cs = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
moo_seterrbfmt (moo, MOO_EINVAL, "parameter not fpdec - %O", x);
|
||||
return MOO_NULL;
|
||||
}
|
||||
|
||||
if (ns < 0) ns = 0;
|
||||
if (cs == ns) return x; /* no change needed */
|
||||
|
||||
if (cs > ns)
|
||||
{
|
||||
/* same as moo_truncfpdecval() */
|
||||
do
|
||||
{
|
||||
/* TODO: optimization... less divisions */
|
||||
xv = moo_divints(moo, xv, MOO_SMOOI_TO_OOP(10), 0, MOO_NULL);
|
||||
if (!xv) return MOO_NULL;
|
||||
cs--;
|
||||
}
|
||||
while (cs > ns);
|
||||
}
|
||||
else /*if (cs < ns)*/
|
||||
{
|
||||
do
|
||||
{
|
||||
xv = moo_mulints(moo, xv, MOO_SMOOI_TO_OOP(10));
|
||||
if (!xv) return MOO_NULL;
|
||||
cs++;
|
||||
}
|
||||
while (cs < ns);
|
||||
}
|
||||
|
||||
/* moo_makefpdec returns xv if ns <= 0. so it's safe to call it
|
||||
* without checks against the 'ns <= 0' condition.
|
||||
* setting ns to 0 or less will converts a decimal to an integer */
|
||||
return moo_makefpdec(moo, xv, ns);
|
||||
}
|
||||
|
||||
moo_oop_t moo_addnums (moo_t* moo, moo_oop_t x, moo_oop_t y)
|
||||
{
|
||||
if (!MOO_OOP_IS_FPDEC(moo, x) && !MOO_OOP_IS_FPDEC(moo, y))
|
||||
|
Reference in New Issue
Block a user