aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPaul Eggert1997-10-23 04:29:36 +0000
committerPaul Eggert1997-10-23 04:29:36 +0000
commitf356c3fb99e8653757a9313f23d2ef45f7df5ac8 (patch)
treecab7097e0bb76b715b24c9155a72f37098c074aa
parent9913ef5adbff04f7e4a7bf1839ada8fbc11aed62 (diff)
downloademacs-f356c3fb99e8653757a9313f23d2ef45f7df5ac8.tar.gz
emacs-f356c3fb99e8653757a9313f23d2ef45f7df5ac8.zip
(_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.
-rw-r--r--src/print.c60
1 files changed, 57 insertions, 3 deletions
diff --git a/src/print.c b/src/print.c
index 6150da41655..237bccc5a65 100644
--- a/src/print.c
+++ b/src/print.c
@@ -45,6 +45,46 @@ extern Lisp_Object Qbackquote, Qcomma, Qcomma_at, Qcomma_dot, Qfunction;
45 45
46#ifdef LISP_FLOAT_TYPE 46#ifdef LISP_FLOAT_TYPE
47Lisp_Object Vfloat_output_format, Qfloat_output_format; 47Lisp_Object Vfloat_output_format, Qfloat_output_format;
48
49/* Work around a problem that happens because math.h on hpux 7
50 defines two static variables--which, in Emacs, are not really static,
51 because `static' is defined as nothing. The problem is that they are
52 defined both here and in lread.c.
53 These macros prevent the name conflict. */
54#if defined (HPUX) && !defined (HPUX8)
55#define _MAXLDBL print_maxldbl
56#define _NMAXLDBL print_nmaxldbl
57#endif
58
59#include <math.h>
60
61#if STDC_HEADERS
62#include <float.h>
63#include <stdlib.h>
64#endif
65
66/* Default to values appropriate for IEEE floating point. */
67#ifndef FLT_RADIX
68#define FLT_RADIX 2
69#endif
70#ifndef DBL_MANT_DIG
71#define DBL_MANT_DIG 53
72#endif
73#ifndef DBL_DIG
74#define DBL_DIG 15
75#endif
76
77/* Define DOUBLE_DIGITS_BOUND, an upper bound on the number of decimal digits
78 needed to express a float without losing information.
79 The general-case formula is valid for the usual case, IEEE floating point,
80 but many compilers can't optimize the formula to an integer constant,
81 so make a special case for it. */
82#if FLT_RADIX == 2 && DBL_MANT_DIG == 53
83#define DOUBLE_DIGITS_BOUND 17 /* IEEE floating point */
84#else
85#define DOUBLE_DIGITS_BOUND ((int) ceil (log10 (pow (FLT_RADIX, DBL_MANT_DIG))))
86#endif
87
48#endif /* LISP_FLOAT_TYPE */ 88#endif /* LISP_FLOAT_TYPE */
49 89
50/* Avoid actual stack overflow in print. */ 90/* Avoid actual stack overflow in print. */
@@ -865,8 +905,21 @@ float_to_string (buf, data)
865 || !STRINGP (Vfloat_output_format)) 905 || !STRINGP (Vfloat_output_format))
866 lose: 906 lose:
867 { 907 {
868 sprintf (buf, "%.17g", data); 908 /* Generate the fewest number of digits that represent the
869 width = -1; 909 floating point value without losing information.
910 The following method is simple but a bit slow.
911 For ideas about speeding things up, please see:
912
913 Guy L Steele Jr & Jon L White, How to print floating-point numbers
914 accurately. SIGPLAN notices 25, 6 (June 1990), 112-126.
915
916 Robert G Burger & R Kent Dybvig, Printing floating point numbers
917 quickly and accurately, SIGPLAN notices 31, 5 (May 1996), 108-116. */
918
919 width = fabs (data) < DBL_MIN ? 1 : DBL_DIG;
920 do
921 sprintf (buf, "%.*g", width, data);
922 while (width++ < DOUBLE_DIGITS_BOUND && atof (buf) != data);
870 } 923 }
871 else /* oink oink */ 924 else /* oink oink */
872 { 925 {
@@ -1514,7 +1567,8 @@ Use `g' to choose the shorter of those two formats for the number at hand.\n\
1514The precision in any of these cases is the number of digits following\n\ 1567The precision in any of these cases is the number of digits following\n\
1515the decimal point. With `f', a precision of 0 means to omit the\n\ 1568the decimal point. With `f', a precision of 0 means to omit the\n\
1516decimal point. 0 is not allowed with `e' or `g'.\n\n\ 1569decimal point. 0 is not allowed with `e' or `g'.\n\n\
1517A value of nil means to use `%.17g'."); 1570A value of nil means to use the shortest notation\n\
1571that represents the number without losing information.");
1518 Vfloat_output_format = Qnil; 1572 Vfloat_output_format = Qnil;
1519 Qfloat_output_format = intern ("float-output-format"); 1573 Qfloat_output_format = intern ("float-output-format");
1520 staticpro (&Qfloat_output_format); 1574 staticpro (&Qfloat_output_format);