Skip to content

Commit d8bacc6

Browse files
authored
VpFormatSt O(n^2) to O(n) (#384)
1 parent 9735c24 commit d8bacc6

2 files changed

Lines changed: 22 additions & 16 deletions

File tree

ext/bigdecimal/bigdecimal.c

Lines changed: 20 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -5704,25 +5704,29 @@ VPrint(FILE *fp, const char *cntl_chr, Real *a)
57045704
static void
57055705
VpFormatSt(char *psz, size_t fFmt)
57065706
{
5707-
size_t ie, i, nf = 0;
5708-
char ch;
5707+
size_t iend, idig = 0, iexp = 0, nspaces;
5708+
char *p;
57095709

57105710
if (fFmt == 0) return;
57115711

5712-
ie = strlen(psz);
5713-
for (i = 0; i < ie; ++i) {
5714-
ch = psz[i];
5715-
if (!ch) break;
5716-
if (ISSPACE(ch) || ch=='-' || ch=='+') continue;
5717-
if (ch == '.') { nf = 0; continue; }
5718-
if (ch == 'E' || ch == 'e') break;
5719-
5720-
if (++nf > fFmt) {
5721-
memmove(psz + i + 1, psz + i, ie - i + 1);
5722-
++ie;
5723-
nf = 0;
5724-
psz[i] = ' ';
5725-
}
5712+
iend = strlen(psz);
5713+
5714+
if ((p = strchr(psz, '.'))) {
5715+
idig = (p - psz) + 1;
5716+
}
5717+
if ((p = strchr(psz, 'E')) || (p = strchr(psz, 'e'))) {
5718+
iexp = p - psz;
5719+
}
5720+
if (idig == 0 || idig > iexp) return;
5721+
5722+
nspaces = (iexp - idig - 1) / fFmt;
5723+
p = psz + iend + 1;
5724+
for (size_t i = nspaces; i > 0; i--) {
5725+
char *src = psz + idig + i * fFmt;
5726+
char *dst = psz + idig + i * (fFmt + 1);
5727+
memmove(dst, src, p - src);
5728+
dst[-1] = ' ';
5729+
p = src;
57265730
}
57275731
}
57285732

test/bigdecimal/test_bigdecimal.rb

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1601,6 +1601,8 @@ def test_to_s
16011601
assert_equal('+1000000 0000000.0', BigDecimal('10000000000000').to_s('+7F'))
16021602
assert_equal('0.1234567890123456789e3', BigDecimal('123.45678901234567890').to_s)
16031603
assert_equal('0.12345 67890 12345 6789e3', BigDecimal('123.45678901234567890').to_s(5))
1604+
assert_equal('0.123456 789012 345678e3', BigDecimal('123.456789012345678').to_s(6))
1605+
assert_equal('0.123456 789012 345678 9e3', BigDecimal('123.4567890123456789').to_s(6))
16041606
end
16051607

16061608
def test_split

0 commit comments

Comments
 (0)