From 9a1e6760a8fb228c292b00a8e32ca11b0c074134 Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Mon, 13 Mar 2023 16:07:17 +0900 Subject: [PATCH] mruby-bigint: add new functions mrb_bint_add_d, mrb_bint_sub_d Those functions do not normalize the return value to avoid repeated conversions between Bigints and (small) Integers. --- include/mruby/internal.h | 2 ++ mrbgems/mruby-bigint/core/bigint.c | 24 ++++++++++++++++++++---- 2 files changed, 22 insertions(+), 4 deletions(-) diff --git a/include/mruby/internal.h b/include/mruby/internal.h index 2e411ce6e..02e85d656 100644 --- a/include/mruby/internal.h +++ b/include/mruby/internal.h @@ -183,6 +183,8 @@ mrb_value mrb_bint_new_str(mrb_state *mrb, const char *x, mrb_int len, mrb_int b 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); mrb_value mrb_bint_sub(mrb_state *mrb, mrb_value x, mrb_value y); +mrb_value mrb_bint_add_d(mrb_state *mrb, mrb_value x, mrb_value y); +mrb_value mrb_bint_sub_d(mrb_state *mrb, mrb_value x, mrb_value y); mrb_value mrb_bint_mul(mrb_state *mrb, mrb_value x, mrb_value y); mrb_value mrb_bint_div(mrb_state *mrb, mrb_value x, mrb_value y); mrb_value mrb_bint_divmod(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 7ba9b1adf..3af5b2da9 100644 --- a/mrbgems/mruby-bigint/core/bigint.c +++ b/mrbgems/mruby-bigint/core/bigint.c @@ -1179,8 +1179,9 @@ mrb_bint_as_uint64(mrb_state *mrb, mrb_value x) return u; } +/* unnormalize version of mrb_bint_add */ mrb_value -mrb_bint_add(mrb_state *mrb, mrb_value x, mrb_value y) +mrb_bint_add_d(mrb_state *mrb, mrb_value x, mrb_value y) { #ifndef MRB_NO_FLOAT if (mrb_float_p(y)) { @@ -1194,11 +1195,19 @@ mrb_bint_add(mrb_state *mrb, mrb_value x, mrb_value y) struct RBigint *b2 = RBIGINT(y); struct RBigint *b3 = bint_new(mrb); mpz_add(mrb, &b3->mp, &b->mp, &b2->mp); - return bint_norm(mrb, b3); + return mrb_obj_value(b3); } mrb_value -mrb_bint_sub(mrb_state *mrb, mrb_value x, mrb_value y) +mrb_bint_add(mrb_state *mrb, mrb_value x, mrb_value y) +{ + x = mrb_bint_add_d(mrb, x, y); + return bint_norm(mrb, RBIGINT(x)); +} + +/* unnormalize version of mrb_bint_sub */ +mrb_value +mrb_bint_sub_d(mrb_state *mrb, mrb_value x, mrb_value y) { #ifndef MRB_NO_FLOAT if (mrb_float_p(y)) { @@ -1212,7 +1221,14 @@ mrb_bint_sub(mrb_state *mrb, mrb_value x, mrb_value y) struct RBigint *b2 = RBIGINT(y); struct RBigint *b3 = bint_new(mrb); mpz_sub(mrb, &b3->mp, &b->mp, &b2->mp); - return bint_norm(mrb, b3); + return mrb_obj_value(b3); +} + +mrb_value +mrb_bint_sub(mrb_state *mrb, mrb_value x, mrb_value y) +{ + x = mrb_bint_sub_d(mrb, x, y); + return bint_norm(mrb, RBIGINT(x)); } mrb_value