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); }