summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark H Weaver <mhw@netris.org>2013-03-19 03:25:59 -0400
committerMark H Weaver <mhw@netris.org>2013-03-19 03:38:15 -0400
commit8150dfa1f2f84d151ced5f723dc69ce0cae1cd32 (patch)
tree477ae2d067c5327f531aa3fd3ccf4251f137fcc6
parenta9ea4f909b9970c755b0a7c4cd9da907e66496fc (diff)
downloadguile-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.c63
-rw-r--r--test-suite/tests/numbers.test4
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)