mirror of
https://github.com/mruby/mruby
synced 2026-06-08 16:11:16 +00:00
mruby-bigint (mrb_bint_2comp): simplify using mpz_2comp()
This commit is contained in:
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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';
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user