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:
parent
a9ea4f909b
commit
8150dfa1f2
2 changed files with 50 additions and 17 deletions
|
@ -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);
|
||||||
|
|
|
@ -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)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue