diff options
author | Mark H Weaver <mhw@netris.org> | 2013-03-19 03:25:59 -0400 |
---|---|---|
committer | Mark H Weaver <mhw@netris.org> | 2013-03-19 03:38:15 -0400 |
commit | 8150dfa1f2f84d151ced5f723dc69ce0cae1cd32 (patch) | |
tree | 477ae2d067c5327f531aa3fd3ccf4251f137fcc6 | |
parent | a9ea4f909b9970c755b0a7c4cd9da907e66496fc (diff) | |
download | guile-8150dfa1f2f84d151ced5f723dc69ce0cae1cd32.tar.gz |
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.
-rw-r--r-- | libguile/numbers.c | 63 | ||||
-rw-r--r-- | test-suite/tests/numbers.test | 4 |
2 files changed, 50 insertions, 17 deletions
diff --git a/libguile/numbers.c b/libguile/numbers.c index c641e3fbd..1f845a365 100644 --- a/libguile/numbers.c +++ b/libguile/numbers.c @@ -5297,6 +5297,7 @@ idbl2str (double dbl, char *a, int radix) int e, k; mpz_t f, r, s, mplus, mminus, hi, digit; int f_is_even, f_is_odd; + int expon; int show_exp = 0; 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 */ - show_exp = k - 1; - k = 1; - } - else if (k <= 0) - { - int i; + if (k <= -3) + { + /* Use scientific notation */ + show_exp = 1; + k = 1; + } + else + { + int i; - /* Print leading zeroes */ - a[ch++] = '0'; - a[ch++] = '.'; - for (i = 0; i > k; i--) - a[ch++] = '0'; + /* Print leading zeroes */ + a[ch++] = '0'; + a[ch++] = '.'; + for (i = 0; i > k; i--) + a[ch++] = '0'; + } } for (;;) @@ -5429,9 +5434,33 @@ idbl2str (double dbl, char *a, int radix) if (k > 0) { - for (; k > 0; k--) - a[ch++] = '0'; - a[ch++] = '.'; + if (expon >= 7 && k >= 4 && expon >= k) + { + /* 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) @@ -5440,7 +5469,7 @@ idbl2str (double dbl, char *a, int radix) if (show_exp) { 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); diff --git a/test-suite/tests/numbers.test b/test-suite/tests/numbers.test index 8f01633db..be2e31732 100644 --- a/test-suite/tests/numbers.test +++ b/test-suite/tests/numbers.test @@ -1429,6 +1429,10 @@ (pass-if (string=? (number->string 35 36) "z")) (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" (for-each (lambda (radix) |