mirror of
https://github.com/ruby/ruby.git
synced 2026-11-08 01:20:26 +08:00
Extract ruby_convert_to_digits inline function
For arbitrary base within 2..36, including 10.
This commit is contained in:
parent
a990df74db
commit
4faedd7373
Notes:
git
2026-11-02 08:39:44 +00:00
40
bignum.c
40
bignum.c
@ -4822,7 +4822,6 @@ big2str_2bdigits(struct big2str_struct *b2s, BDIGIT *xds, size_t xn, size_t tail
|
||||
{
|
||||
size_t j;
|
||||
BDIGIT_DBL num;
|
||||
char buf[SIZEOF_BDIGIT_DBL*CHAR_BIT], *p;
|
||||
int beginning = !b2s->ptr;
|
||||
size_t len = 0;
|
||||
|
||||
@ -4830,45 +4829,24 @@ big2str_2bdigits(struct big2str_struct *b2s, BDIGIT *xds, size_t xn, size_t tail
|
||||
num = bary2bdigitdbl(xds, xn);
|
||||
|
||||
if (beginning) {
|
||||
char buf[SIZEOF_BDIGIT_DBL*CHAR_BIT], *p = buf;
|
||||
if (num == 0)
|
||||
return;
|
||||
p = buf;
|
||||
j = sizeof(buf);
|
||||
if (b2s->base == 10) {
|
||||
/* Emit two decimal digits per iteration from ruby_decimal_digit_pairs.
|
||||
* See the comment on the table in bignum.c near ruby_digitmap. */
|
||||
j -= ruby_convert_to_decimals(&p[j], num);
|
||||
}
|
||||
else {
|
||||
do {
|
||||
unsigned int idx = (unsigned int)(num % b2s->base);
|
||||
num /= b2s->base;
|
||||
p[--j] = ruby_digitmap[idx];
|
||||
} while (num);
|
||||
}
|
||||
j -= ruby_convert_to_digits(&p[j], num, b2s->base);
|
||||
len = sizeof(buf) - j;
|
||||
big2str_alloc(b2s, len + taillen);
|
||||
MEMCPY(b2s->ptr, buf + j, char, len);
|
||||
}
|
||||
else {
|
||||
p = b2s->ptr;
|
||||
char *p = b2s->ptr;
|
||||
j = b2s->hbase2_numdigits;
|
||||
if (b2s->base == 10) {
|
||||
/* Non-beginning chunks must emit EXACTLY hbase2_numdigits,
|
||||
* zero-padded on the left. Consume num in 2-digit groups,
|
||||
* handle the odd trailing digit, then memset remaining
|
||||
* positions with '0'. */
|
||||
j -= ruby_convert_to_decimals(&p[j], num);
|
||||
if (j > 0) {
|
||||
memset(p, '0', j);
|
||||
}
|
||||
}
|
||||
else {
|
||||
do {
|
||||
unsigned int idx = (unsigned int)(num % b2s->base);
|
||||
num /= b2s->base;
|
||||
p[--j] = ruby_digitmap[idx];
|
||||
} while (j);
|
||||
j -= ruby_convert_to_digits(&p[j], num, b2s->base);
|
||||
/* Non-beginning chunks must emit EXACTLY hbase2_numdigits,
|
||||
* zero-padded on the left. Consume num, then memset
|
||||
* remaining positions with '0'. */
|
||||
if (j > 0) {
|
||||
memset(p, '0', j);
|
||||
}
|
||||
len = b2s->hbase2_numdigits;
|
||||
}
|
||||
|
||||
@ -143,6 +143,25 @@ ruby_convert_to_decimals(char *dest, BDIGIT_DBL num)
|
||||
return (size_t)(dest - b);
|
||||
}
|
||||
|
||||
/* Stores the string for num using base as the radix, backward from
|
||||
* dest. base must be 2..36. Returns the stored size. */
|
||||
static inline size_t
|
||||
ruby_convert_to_digits(char *dest, BDIGIT_DBL num, unsigned int base)
|
||||
{
|
||||
RBIMPL_ASSERT_OR_ASSUME(base >= 2);
|
||||
RBIMPL_ASSERT_OR_ASSUME(base <= 36);
|
||||
if (base == 10) {
|
||||
return ruby_convert_to_decimals(dest, num);
|
||||
}
|
||||
char *b = dest;
|
||||
do {
|
||||
unsigned int idx = (unsigned int)(num % base);
|
||||
num /= base;
|
||||
*--b = ruby_digitmap[idx];
|
||||
} while (num);
|
||||
return (size_t)(dest - b);
|
||||
}
|
||||
|
||||
double rb_big_fdiv_double(VALUE x, VALUE y);
|
||||
VALUE rb_big_uminus(VALUE x);
|
||||
VALUE rb_big_hash(VALUE);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user