diff --git a/include/mruby/internal.h b/include/mruby/internal.h index 96efc7697..ccfd30769 100644 --- a/include/mruby/internal.h +++ b/include/mruby/internal.h @@ -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); diff --git a/mrbgems/mruby-bigint/core/bigint.c b/mrbgems/mruby-bigint/core/bigint.c index a3457e275..cca54d31f 100644 --- a/mrbgems/mruby-bigint/core/bigint.c +++ b/mrbgems/mruby-bigint/core/bigint.c @@ -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; ip[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) {