зеркало из https://github.com/github/ruby.git
[ruby/bigdecimal] Add .to_s('F') digit grouping for integer part
https://github.com/ruby/bigdecimal/commit/f63544d465
This commit is contained in:
Родитель
1dde9d7260
Коммит
10f59dcbcd
|
@ -2689,7 +2689,7 @@ BigDecimal_ceil(int argc, VALUE *argv, VALUE self)
|
||||||
* A space at the start of s returns positive values with a leading space.
|
* A space at the start of s returns positive values with a leading space.
|
||||||
*
|
*
|
||||||
* If s contains a number, a space is inserted after each group of that many
|
* If s contains a number, a space is inserted after each group of that many
|
||||||
* fractional digits.
|
* digits, starting from '.' and counting outwards.
|
||||||
*
|
*
|
||||||
* If s ends with an 'E', engineering notation (0.xxxxEnn) is used.
|
* If s ends with an 'E', engineering notation (0.xxxxEnn) is used.
|
||||||
*
|
*
|
||||||
|
@ -6706,95 +6706,90 @@ VpToFString(Real *a, char *buf, size_t buflen, size_t fFmt, int fPlus)
|
||||||
/* fPlus = 0: default, 1: set ' ' before digits, 2: set '+' before digits. */
|
/* fPlus = 0: default, 1: set ' ' before digits, 2: set '+' before digits. */
|
||||||
{
|
{
|
||||||
size_t i, n;
|
size_t i, n;
|
||||||
DECDIG m, e, nn;
|
DECDIG m, e;
|
||||||
char *p = buf;
|
char *p = buf;
|
||||||
size_t plen = buflen;
|
size_t plen = buflen, delim = fFmt;
|
||||||
ssize_t ex;
|
ssize_t ex;
|
||||||
|
|
||||||
if (VpToSpecialString(a, buf, buflen, fPlus)) return;
|
if (VpToSpecialString(a, buf, buflen, fPlus)) return;
|
||||||
|
|
||||||
#define ADVANCE(n) do { \
|
#define APPEND(c, group) do { \
|
||||||
if (plen < n) goto overflow; \
|
if (plen < 1) goto overflow; \
|
||||||
p += n; \
|
if (group && delim == 0) { \
|
||||||
plen -= n; \
|
*p = ' '; \
|
||||||
|
p += 1; \
|
||||||
|
plen -= 1; \
|
||||||
|
} \
|
||||||
|
if (plen < 1) goto overflow; \
|
||||||
|
*p = c; \
|
||||||
|
p += 1; \
|
||||||
|
plen -= 1; \
|
||||||
|
if (group) delim = (delim + 1) % fFmt; \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
|
|
||||||
if (BIGDECIMAL_NEGATIVE_P(a)) {
|
if (BIGDECIMAL_NEGATIVE_P(a)) {
|
||||||
*p = '-';
|
APPEND('-', false);
|
||||||
ADVANCE(1);
|
|
||||||
}
|
}
|
||||||
else if (fPlus == 1) {
|
else if (fPlus == 1) {
|
||||||
*p = ' ';
|
APPEND(' ', false);
|
||||||
ADVANCE(1);
|
|
||||||
}
|
}
|
||||||
else if (fPlus == 2) {
|
else if (fPlus == 2) {
|
||||||
*p = '+';
|
APPEND('+', false);
|
||||||
ADVANCE(1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
n = a->Prec;
|
n = a->Prec;
|
||||||
ex = a->exponent;
|
ex = a->exponent;
|
||||||
if (ex <= 0) {
|
if (ex <= 0) {
|
||||||
*p = '0'; ADVANCE(1);
|
APPEND('0', false);
|
||||||
*p = '.'; ADVANCE(1);
|
APPEND('.', false);
|
||||||
while (ex < 0) {
|
}
|
||||||
for (i=0; i < BASE_FIG; ++i) {
|
while (ex < 0) {
|
||||||
*p = '0'; ADVANCE(1);
|
for (i=0; i < BASE_FIG; ++i) {
|
||||||
}
|
APPEND('0', fFmt > 0);
|
||||||
++ex;
|
|
||||||
}
|
}
|
||||||
ex = -1;
|
++ex;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < n; ++i) {
|
for (i = 0; i < n; ++i) {
|
||||||
--ex;
|
m = BASE1;
|
||||||
if (i == 0 && ex >= 0) {
|
e = a->frac[i];
|
||||||
size_t n = snprintf(p, plen, "%lu", (unsigned long)a->frac[i]);
|
if (i == 0 && ex > 0) {
|
||||||
if (n > plen) goto overflow;
|
for (delim = 0; e / m == 0; delim++) {
|
||||||
ADVANCE(n);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
m = BASE1;
|
|
||||||
e = a->frac[i];
|
|
||||||
while (m) {
|
|
||||||
nn = e / m;
|
|
||||||
*p = (char)(nn + '0');
|
|
||||||
ADVANCE(1);
|
|
||||||
e = e - nn * m;
|
|
||||||
m /= 10;
|
m /= 10;
|
||||||
}
|
}
|
||||||
|
if (fFmt > 0) {
|
||||||
|
delim = 2*fFmt - (ex * BASE_FIG - delim) % fFmt;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (ex == 0) {
|
while (m && (e || (i < n - 1) || ex > 0)) {
|
||||||
*p = '.';
|
APPEND((char)(e / m + '0'), fFmt > 0);
|
||||||
ADVANCE(1);
|
e %= m;
|
||||||
|
m /= 10;
|
||||||
|
}
|
||||||
|
if (--ex == 0) {
|
||||||
|
APPEND('.', false);
|
||||||
|
delim = fFmt;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
while (--ex>=0) {
|
|
||||||
m = BASE;
|
while (ex > 0) {
|
||||||
while (m /= 10) {
|
for (i=0; i < BASE_FIG; ++i) {
|
||||||
*p = '0';
|
APPEND('0', fFmt > 0);
|
||||||
ADVANCE(1);
|
|
||||||
}
|
}
|
||||||
if (ex == 0) {
|
if (--ex == 0) {
|
||||||
*p = '.';
|
APPEND('.', false);
|
||||||
ADVANCE(1);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
*p = '\0';
|
*p = '\0';
|
||||||
while (p - 1 > buf && p[-1] == '0') {
|
|
||||||
*(--p) = '\0';
|
|
||||||
++plen;
|
|
||||||
}
|
|
||||||
if (p - 1 > buf && p[-1] == '.') {
|
if (p - 1 > buf && p[-1] == '.') {
|
||||||
snprintf(p, plen, "0");
|
snprintf(p, plen, "0");
|
||||||
}
|
}
|
||||||
if (fFmt) VpFormatSt(buf, fFmt);
|
|
||||||
|
|
||||||
overflow:
|
overflow:
|
||||||
return;
|
return;
|
||||||
#undef ADVANCE
|
#undef APPEND
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -1415,9 +1415,13 @@ class TestBigDecimal < Test::Unit::TestCase
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_to_s
|
def test_to_s
|
||||||
assert_equal('-123.45678 90123 45678 9', BigDecimal('-123.45678901234567890').to_s('5F'))
|
assert_equal('0.0', BigDecimal('0').to_s)
|
||||||
assert_equal('+123.45678901 23456789', BigDecimal('123.45678901234567890').to_s('+8F'))
|
assert_equal('-123 45678 90123.45678 90123 45678 9', BigDecimal('-1234567890123.45678901234567890').to_s('5F'))
|
||||||
assert_equal(' 123.4567890123456789', BigDecimal('123.45678901234567890').to_s(' F'))
|
assert_equal('+12345 67890123.45678901 23456789', BigDecimal('1234567890123.45678901234567890').to_s('+8F'))
|
||||||
|
assert_equal(' 1234567890123.4567890123456789', BigDecimal('1234567890123.45678901234567890').to_s(' F'))
|
||||||
|
assert_equal('100 000 000 000.000 000 000 01', BigDecimal('100000000000.00000000001').to_s('3F'))
|
||||||
|
assert_equal('0.0 0 0 0 0 0 0 0 0 0 0 0 1', BigDecimal('0.0000000000001').to_s('1F'))
|
||||||
|
assert_equal('+1000000 0000000.0', BigDecimal('10000000000000').to_s('+7F'))
|
||||||
assert_equal('0.1234567890123456789e3', BigDecimal('123.45678901234567890').to_s)
|
assert_equal('0.1234567890123456789e3', BigDecimal('123.45678901234567890').to_s)
|
||||||
assert_equal('0.12345 67890 12345 6789e3', BigDecimal('123.45678901234567890').to_s(5))
|
assert_equal('0.12345 67890 12345 6789e3', BigDecimal('123.45678901234567890').to_s(5))
|
||||||
end
|
end
|
||||||
|
|
Загрузка…
Ссылка в новой задаче