diff options
| author | Paul Eggert | 1997-10-23 04:29:36 +0000 |
|---|---|---|
| committer | Paul Eggert | 1997-10-23 04:29:36 +0000 |
| commit | f356c3fb99e8653757a9313f23d2ef45f7df5ac8 (patch) | |
| tree | cab7097e0bb76b715b24c9155a72f37098c074aa | |
| parent | 9913ef5adbff04f7e4a7bf1839ada8fbc11aed62 (diff) | |
| download | emacs-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.c | 60 |
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 |
| 47 | Lisp_Object Vfloat_output_format, Qfloat_output_format; | 47 | Lisp_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\ | |||
| 1514 | The precision in any of these cases is the number of digits following\n\ | 1567 | The precision in any of these cases is the number of digits following\n\ |
| 1515 | the decimal point. With `f', a precision of 0 means to omit the\n\ | 1568 | the decimal point. With `f', a precision of 0 means to omit the\n\ |
| 1516 | decimal point. 0 is not allowed with `e' or `g'.\n\n\ | 1569 | decimal point. 0 is not allowed with `e' or `g'.\n\n\ |
| 1517 | A value of nil means to use `%.17g'."); | 1570 | A value of nil means to use the shortest notation\n\ |
| 1571 | that 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); |