From bf081c3d3da3db7d443fd8d56bc4f27c54b8d2f9 Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Thu, 25 Jul 2024 17:46:36 +0900 Subject: [PATCH] mruby-bigint (mrb_bint_and): further optimization for `bint & int` --- mrbgems/mruby-bigint/core/bigint.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/mrbgems/mruby-bigint/core/bigint.c b/mrbgems/mruby-bigint/core/bigint.c index 458269476..ad0073ad3 100644 --- a/mrbgems/mruby-bigint/core/bigint.c +++ b/mrbgems/mruby-bigint/core/bigint.c @@ -1663,17 +1663,25 @@ mrb_value mrb_bint_and(mrb_state *mrb, mrb_value x, mrb_value y) { struct RBigint *b1 = RBIGINT(x); - struct RBigint *b3 = bint_new(mrb); if (mrb_integer_p(y)) { mrb_int z = mrb_integer(y); - if (z >= 0 && z < DIG_BASE) { + if (z == 0) return mrb_fixnum_value(0); + if (z > 0 && z < DIG_BASE) { z &= b1->mp.p[0]; return mrb_int_value(mrb, z); } + if (z == -1) return x; + if (z < 0 && -z < DIG_BASE) { + struct RBigint *b3 = bint_new(mrb); + mpz_set(mrb, &b3->mp, &b1->mp); + b3->mp.p[0] &= (mp_limb)z; + return bint_norm(mrb, b3); + } } y = mrb_as_bint(mrb, y); struct RBigint *b2 = RBIGINT(y); + struct RBigint *b3 = bint_new(mrb); mpz_and(mrb, &b3->mp, &b1->mp, &b2->mp); return bint_norm(mrb, b3); }