From 99c078bb6b1f3bbd3e81360982437650dcfedf1c Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Thu, 25 Jul 2024 16:01:16 +0900 Subject: [PATCH] mruby-bigint (mrb_bint_2comp): simplify using mpz_2comp() --- mrbgems/mruby-bigint/core/bigint.c | 34 +++++------------------------ mrbgems/mruby-sprintf/src/sprintf.c | 11 +++++++--- 2 files changed, 13 insertions(+), 32 deletions(-) diff --git a/mrbgems/mruby-bigint/core/bigint.c b/mrbgems/mruby-bigint/core/bigint.c index 187309724..458269476 100644 --- a/mrbgems/mruby-bigint/core/bigint.c +++ b/mrbgems/mruby-bigint/core/bigint.c @@ -1776,40 +1776,16 @@ mrb_bint_hash(mrb_state *mrb, mrb_value x) return mrb_int_value(mrb, hash); } +/* to be used only from mruby-sprintf */ mrb_value -mrb_bint_2comp(mrb_state *mrb, mrb_value x, mrb_int base) +mrb_bint_2comp(mrb_state *mrb, mrb_value x) { struct RBigint *b = RBIGINT(x); - mrb_int i; - for (i=b->mp.sz-1; i>=0; i--) { - if (b->mp.p[i] > 0) break; - } - -#ifdef __GNUC__ - mrb_int dbits = __builtin_ctz(base); -#else - mrb_int dbits; - switch (base) { - case 16: dbits = 4; break; - case 8: dbits = 3; break; - case 2: dbits = 1; break; - } -#endif - mrb_int topbit = DIG_SIZE * (i+1) - lzb(b->mp.p[i]); - mrb_int nbits = (topbit / dbits + 1) * dbits; - - mpz_t one; - mpz_t up; struct RBigint *b2 = bint_new(mrb); - - /* rounding up to nearest power of 2 */ - mpz_init_set_int(mrb, &one, 1); - mpz_init(mrb, &up); - mpz_mul_2exp(mrb, &up, &one, nbits); - mpz_clear(mrb, &one); - mpz_add(mrb, &b2->mp, &up, &b->mp); - mpz_clear(mrb, &up); + mpz_set(mrb, &b2->mp, &b->mp); + mpz_2comp(mrb, &b2->mp); + b2->mp.sn = 1; return mrb_obj_value(b2); } diff --git a/mrbgems/mruby-sprintf/src/sprintf.c b/mrbgems/mruby-sprintf/src/sprintf.c index 3e511d54e..6ebe8fab9 100644 --- a/mrbgems/mruby-sprintf/src/sprintf.c +++ b/mrbgems/mruby-sprintf/src/sprintf.c @@ -17,7 +17,7 @@ #define BITSPERDIG MRB_INT_BIT #define EXTENDSIGN(n, l) (((~0U << (n)) >> (((n)*(l)) % BITSPERDIG)) & ~(~0U << (n))) -mrb_value mrb_bint_2comp(mrb_state *mrb, mrb_value x, mrb_int base); +mrb_value mrb_bint_2comp(mrb_state *mrb, mrb_value x); static char* remove_sign_bits(char *str, int base) @@ -599,7 +599,7 @@ retry: mrb_int n = (mrb_bint_cmp(mrb, val, mrb_fixnum_value(0))); mrb_bool need_dots = ((flags & FPLUS) == 0) && (base == 16 || base == 8 || base == 2) && n < 0; if (need_dots) { - val = mrb_bint_2comp(mrb, val, base); + val = mrb_bint_2comp(mrb, val); dots = 1; v = -1; } @@ -665,6 +665,11 @@ retry: fc = '1'; break; } + if (dots) { + while (*s == fc) { + s++; len--; + } + } if (*p == 'X') { char *pp = s; int c; @@ -672,7 +677,7 @@ retry: *pp = toupper(c); pp++; } - if (base == 16 && fc) { + if (base == 16) { fc = 'F'; } }