mruby-bigint/bigint.c: add 2 new functions for 64 bit integer

- mrb_bint_new_int64()
- mrb_bint_new_uint64()
This commit is contained in:
Yukihiro "Matz" Matsumoto
2023-03-06 17:06:44 +09:00
parent b1d0a3d3aa
commit a3b84fbb08
2 changed files with 59 additions and 0 deletions
+6
View File
@@ -173,6 +173,12 @@ mrb_value mrb_f_send(mrb_state *mrb, mrb_value self);
#ifdef MRB_USE_BIGINT
mrb_value mrb_bint_new_int(mrb_state *mrb, mrb_int x);
#ifdef MRB_INT64
#define mrb_bint_new_int64(mrb,x) mrb_bint_new_int((mrb),(mrb_int)(x))
#else
mrb_value mrb_bint_new_int64(mrb_state *mrb, int64_t x);
#endif
mrb_value mrb_bint_new_uint64(mrb_state *mrb, uint64_t x);
mrb_value mrb_bint_new_str(mrb_state *mrb, const char *x, mrb_int len, mrb_int base);
mrb_value mrb_as_bint(mrb_state *mrb, mrb_value x);
mrb_value mrb_bint_add(mrb_state *mrb, mrb_value x, mrb_value y);
+53
View File
@@ -97,6 +97,39 @@ mpz_set_int(mrb_state *mrb, mpz_t *y, mrb_int v)
}
}
static void
mpz_set_uint64(mrb_state *mrb, mpz_t *y, uint64_t u)
{
const size_t len = sizeof(uint64_t) / sizeof(mp_limb);
y->sn = (u != 0);
mpz_realloc(mrb, y, len);
for (size_t i=0; i<len; i++) {
y->p[i++] = (mp_limb)LOW(u);
u >>= DIG_SIZE;
}
}
#ifdef MRB_INT32
static void
mpz_set_int64(mrb_state *mrb, mpz_t *y, int64_t v)
{
uint64_t u;
if (v < 0) {
if (v == INT64_MIN) u = v;
else u = -v;
}
else {
u = v;
}
mpz_set_uint64(mrb, y, u);
if (v < 0) {
y->sn = -1;
}
}
#endif
static void
mpz_init_set_int(mrb_state *mrb, mpz_t *y, mrb_int v)
{
@@ -969,6 +1002,26 @@ mrb_bint_new_int(mrb_state *mrb, mrb_int x)
return mrb_obj_value(b);
}
#ifdef MRB_INT32
mrb_value
mrb_bint_new_int64(mrb_state *mrb, int64_t x)
{
struct RBigint *b = bint_new(mrb);
mpz_init(mrb, &b->mp);
mpz_set_int64(mrb, &b->mp, x);
return mrb_obj_value(b);
}
#endif
mrb_value
mrb_bint_new_uint64(mrb_state *mrb, uint64_t x)
{
struct RBigint *b = bint_new(mrb);
mpz_init(mrb, &b->mp);
mpz_set_uint64(mrb, &b->mp, x);
return mrb_obj_value(b);
}
mrb_value
mrb_bint_new_str(mrb_state *mrb, const char *x, mrb_int len, mrb_int base)
{