Single-precision floats now print differently from their double-precision

counterparts.
This commit is contained in:
Vincent St-Amour 2011-01-14 12:47:28 -05:00
parent d220e0a10b
commit c997ae139b
2 changed files with 58 additions and 9 deletions

View File

@ -140,6 +140,17 @@
(test "+nan.0" number->string +nan.0) (test "+nan.0" number->string +nan.0)
(test "+nan.0" number->string +nan.0) (test "+nan.0" number->string +nan.0)
(test "+inf.f" number->string +inf.f)
(test "-inf.f" number->string -inf.f)
(test "+nan.f" number->string +nan.f)
(test "+nan.f" number->string +nan.f)
(test "0.0f0" number->string 0.0f0)
(test "0.0f0" number->string 0.0f1)
(test "0.0f0" number->string 0.0f17)
(test "13.25f0" number->string 13.25f0)
(test "13.25f0" number->string 1.325f1)
(test "-4.25f0" number->string -4.25f0)
(map (lambda (n) (map (lambda (n)
;; test that fresh strings are generated: ;; test that fresh strings are generated:
(let ([n1 (number->string n)] (let ([n1 (number->string n)]

View File

@ -1521,22 +1521,49 @@ string_to_number (int argc, Scheme_Object *argv[])
} }
static char *double_to_string (double d, int alloc) static char *double_to_string (double d, int alloc, int was_single)
{ {
char buffer[100], *s; char buffer[100], *s;
int l, i, digits; int l, i, digits;
if (MZ_IS_NAN(d)) if (MZ_IS_NAN(d))
#ifdef MZ_USE_SINGLE_FLOATS
if (was_single)
s = single_not_a_number_str;
else
#endif
s = not_a_number_str; s = not_a_number_str;
else if (MZ_IS_POS_INFINITY(d)) else if (MZ_IS_POS_INFINITY(d))
#ifdef MZ_USE_SINGLE_FLOATS
if (was_single)
s = single_infinity_str;
else
#endif
s = infinity_str; s = infinity_str;
else if (MZ_IS_NEG_INFINITY(d)) else if (MZ_IS_NEG_INFINITY(d))
#ifdef MZ_USE_SINGLE_FLOATS
if (was_single)
s = single_minus_infinity_str;
else
#endif
s = minus_infinity_str; s = minus_infinity_str;
else if (d == 0.0) { else if (d == 0.0) {
/* Check for -0.0, since some printers get it wrong. */ /* Check for -0.0, since some printers get it wrong. */
if (scheme_minus_zero_p(d)) if (scheme_minus_zero_p(d))
#ifdef MZ_USE_SINGLE_FLOATS
if (was_single)
/* The f0 suffix causes the string to be read as a single-
precision float. */
s = "-0.0f0";
else
#endif
s = "-0.0"; s = "-0.0";
else else
#ifdef MZ_USE_SINGLE_FLOATS
if (was_single)
s = "0.0f0";
else
#endif
s = "0.0"; s = "0.0";
} else { } else {
/* Initial count for significant digits is 14. That's big enough to /* Initial count for significant digits is 14. That's big enough to
@ -1568,6 +1595,17 @@ static char *double_to_string (double d, int alloc)
buffer[i + 2] = 0; buffer[i + 2] = 0;
l += 2; l += 2;
} }
#ifdef MZ_USE_SINGLE_FLOATS
if (was_single) {
/* In case of a single-precision float, add the f0 suffix to
cause the string to be read back as a single-precision
float. */
buffer[l] = 'f';
buffer[l + 1] = '0';
buffer[l + 2] = 0;
l += 2;
}
#endif
s = (char *)scheme_malloc_atomic(strlen(buffer) + 1); s = (char *)scheme_malloc_atomic(strlen(buffer) + 1);
strcpy(s, buffer); strcpy(s, buffer);
@ -1594,7 +1632,7 @@ static char *number_to_allocated_string(int radix, Scheme_Object *obj, int alloc
scheme_raise_exn(MZEXN_FAIL_CONTRACT, scheme_raise_exn(MZEXN_FAIL_CONTRACT,
"number->string: " "number->string: "
"inexact numbers can only be printed in base 10"); "inexact numbers can only be printed in base 10");
s = double_to_string(SCHEME_FLOAT_VAL(obj), alloc); s = double_to_string(SCHEME_FLOAT_VAL(obj), alloc, SCHEME_FLTP(obj));
} else if (SCHEME_RATIONALP(obj)) { } else if (SCHEME_RATIONALP(obj)) {
Scheme_Object *n, *d; Scheme_Object *n, *d;
char *ns, *ds; char *ns, *ds;
@ -1659,7 +1697,7 @@ int scheme_check_double(const char *where, double d, const char *dest)
"%s: no %s representation for %s", "%s: no %s representation for %s",
where, where,
dest, dest,
double_to_string(d, 0)); double_to_string(d, 0, 0));
return 0; return 0;
} }