mirror of
git://git.sv.gnu.org/emacs.git
synced 2026-03-06 05:52:32 -08:00
(_MAXLDBL, _NMAXLDBL):
Define to work around hpux 7 <math.h> problem. (<math.h>): Include. (<float.h>, <stdlib.h>): Include if STDC_HEADERS. (FLT_RADIX, DBL_MANT_DIG, DBL_DIG): Default to IEEE values. (DOUBLE_DIGITS_BOUND): New macro. (float_to_string): By default, generate the fewest number of digits that represent the floating point value exactly.
This commit is contained in:
parent
9913ef5adb
commit
f356c3fb99
1 changed files with 57 additions and 3 deletions
60
src/print.c
60
src/print.c
|
|
@ -45,6 +45,46 @@ extern Lisp_Object Qbackquote, Qcomma, Qcomma_at, Qcomma_dot, Qfunction;
|
|||
|
||||
#ifdef LISP_FLOAT_TYPE
|
||||
Lisp_Object Vfloat_output_format, Qfloat_output_format;
|
||||
|
||||
/* Work around a problem that happens because math.h on hpux 7
|
||||
defines two static variables--which, in Emacs, are not really static,
|
||||
because `static' is defined as nothing. The problem is that they are
|
||||
defined both here and in lread.c.
|
||||
These macros prevent the name conflict. */
|
||||
#if defined (HPUX) && !defined (HPUX8)
|
||||
#define _MAXLDBL print_maxldbl
|
||||
#define _NMAXLDBL print_nmaxldbl
|
||||
#endif
|
||||
|
||||
#include <math.h>
|
||||
|
||||
#if STDC_HEADERS
|
||||
#include <float.h>
|
||||
#include <stdlib.h>
|
||||
#endif
|
||||
|
||||
/* Default to values appropriate for IEEE floating point. */
|
||||
#ifndef FLT_RADIX
|
||||
#define FLT_RADIX 2
|
||||
#endif
|
||||
#ifndef DBL_MANT_DIG
|
||||
#define DBL_MANT_DIG 53
|
||||
#endif
|
||||
#ifndef DBL_DIG
|
||||
#define DBL_DIG 15
|
||||
#endif
|
||||
|
||||
/* Define DOUBLE_DIGITS_BOUND, an upper bound on the number of decimal digits
|
||||
needed to express a float without losing information.
|
||||
The general-case formula is valid for the usual case, IEEE floating point,
|
||||
but many compilers can't optimize the formula to an integer constant,
|
||||
so make a special case for it. */
|
||||
#if FLT_RADIX == 2 && DBL_MANT_DIG == 53
|
||||
#define DOUBLE_DIGITS_BOUND 17 /* IEEE floating point */
|
||||
#else
|
||||
#define DOUBLE_DIGITS_BOUND ((int) ceil (log10 (pow (FLT_RADIX, DBL_MANT_DIG))))
|
||||
#endif
|
||||
|
||||
#endif /* LISP_FLOAT_TYPE */
|
||||
|
||||
/* Avoid actual stack overflow in print. */
|
||||
|
|
@ -865,8 +905,21 @@ float_to_string (buf, data)
|
|||
|| !STRINGP (Vfloat_output_format))
|
||||
lose:
|
||||
{
|
||||
sprintf (buf, "%.17g", data);
|
||||
width = -1;
|
||||
/* Generate the fewest number of digits that represent the
|
||||
floating point value without losing information.
|
||||
The following method is simple but a bit slow.
|
||||
For ideas about speeding things up, please see:
|
||||
|
||||
Guy L Steele Jr & Jon L White, How to print floating-point numbers
|
||||
accurately. SIGPLAN notices 25, 6 (June 1990), 112-126.
|
||||
|
||||
Robert G Burger & R Kent Dybvig, Printing floating point numbers
|
||||
quickly and accurately, SIGPLAN notices 31, 5 (May 1996), 108-116. */
|
||||
|
||||
width = fabs (data) < DBL_MIN ? 1 : DBL_DIG;
|
||||
do
|
||||
sprintf (buf, "%.*g", width, data);
|
||||
while (width++ < DOUBLE_DIGITS_BOUND && atof (buf) != data);
|
||||
}
|
||||
else /* oink oink */
|
||||
{
|
||||
|
|
@ -1514,7 +1567,8 @@ Use `g' to choose the shorter of those two formats for the number at hand.\n\
|
|||
The precision in any of these cases is the number of digits following\n\
|
||||
the decimal point. With `f', a precision of 0 means to omit the\n\
|
||||
decimal point. 0 is not allowed with `e' or `g'.\n\n\
|
||||
A value of nil means to use `%.17g'.");
|
||||
A value of nil means to use the shortest notation\n\
|
||||
that represents the number without losing information.");
|
||||
Vfloat_output_format = Qnil;
|
||||
Qfloat_output_format = intern ("float-output-format");
|
||||
staticpro (&Qfloat_output_format);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue