1
Fork 0
mirror of https://git.savannah.gnu.org/git/guile.git synced 2025-05-20 19:50:24 +02:00

Use scientific notation only if there are enough trailing zeroes.

* libguile/numbers.c (idbl2str): Print large numbers in scientific
  notation only if the exponent is >= 7 and the least significant
  non-zero digit has value >= radix^4.

* test-suite/tests/numbers.test ("number->string"): Add tests.
This commit is contained in:
Mark H Weaver 2013-03-19 03:25:59 -04:00
parent a9ea4f909b
commit 8150dfa1f2
2 changed files with 50 additions and 17 deletions

View file

@ -5297,6 +5297,7 @@ idbl2str (double dbl, char *a, int radix)
int e, k; int e, k;
mpz_t f, r, s, mplus, mminus, hi, digit; mpz_t f, r, s, mplus, mminus, hi, digit;
int f_is_even, f_is_odd; int f_is_even, f_is_odd;
int expon;
int show_exp = 0; int show_exp = 0;
mpz_inits (f, r, s, mplus, mminus, hi, digit, NULL); mpz_inits (f, r, s, mplus, mminus, hi, digit, NULL);
@ -5374,21 +5375,25 @@ idbl2str (double dbl, char *a, int radix)
} }
} }
if (k >= 8 || k <= -3) expon = k - 1;
if (k <= 0)
{ {
/* Use scientific notation */ if (k <= -3)
show_exp = k - 1; {
k = 1; /* Use scientific notation */
} show_exp = 1;
else if (k <= 0) k = 1;
{ }
int i; else
{
int i;
/* Print leading zeroes */ /* Print leading zeroes */
a[ch++] = '0'; a[ch++] = '0';
a[ch++] = '.'; a[ch++] = '.';
for (i = 0; i > k; i--) for (i = 0; i > k; i--)
a[ch++] = '0'; a[ch++] = '0';
}
} }
for (;;) for (;;)
@ -5429,9 +5434,33 @@ idbl2str (double dbl, char *a, int radix)
if (k > 0) if (k > 0)
{ {
for (; k > 0; k--) if (expon >= 7 && k >= 4 && expon >= k)
a[ch++] = '0'; {
a[ch++] = '.'; /* Here we would have to print more than three zeroes
followed by a decimal point and another zero. It
makes more sense to use scientific notation. */
/* Adjust k to what it would have been if we had chosen
scientific notation from the beginning. */
k -= expon;
/* k will now be <= 0, with magnitude equal to the number of
digits that we printed which should now be put after the
decimal point. */
/* Insert a decimal point */
memmove (a + ch + k + 1, a + ch + k, -k);
a[ch + k] = '.';
ch++;
show_exp = 1;
}
else
{
for (; k > 0; k--)
a[ch++] = '0';
a[ch++] = '.';
}
} }
if (k == 0) if (k == 0)
@ -5440,7 +5469,7 @@ idbl2str (double dbl, char *a, int radix)
if (show_exp) if (show_exp)
{ {
a[ch++] = 'e'; a[ch++] = 'e';
ch += scm_iint2str (show_exp, radix, a + ch); ch += scm_iint2str (expon, radix, a + ch);
} }
mpz_clears (f, r, s, mplus, mminus, hi, digit, NULL); mpz_clears (f, r, s, mplus, mminus, hi, digit, NULL);

View file

@ -1429,6 +1429,10 @@
(pass-if (string=? (number->string 35 36) "z")) (pass-if (string=? (number->string 35 36) "z"))
(pass-if (= (num->str->num 35 36) 35)) (pass-if (= (num->str->num 35 36) 35))
(pass-if (string=? (number->string 12342342340000.0) "1.234234234e13"))
(pass-if (string=? (number->string 1234234234000.0) "1234234234000.0"))
(pass-if (string=? (number->string 1240000.0) "1240000.0"))
(with-test-prefix "powers of radix" (with-test-prefix "powers of radix"
(for-each (for-each
(lambda (radix) (lambda (radix)