Commit | Line | Data |
---|---|---|
a451f14b PE |
1 | /* floating point to accurate string |
2 | ||
ab422c4d | 3 | Copyright (C) 2010-2013 Free Software Foundation, Inc. |
a451f14b PE |
4 | |
5 | This program is free software: you can redistribute it and/or modify | |
6 | it under the terms of the GNU General Public License as published by | |
7 | the Free Software Foundation; either version 3 of the License, or | |
8 | (at your option) any later version. | |
9 | ||
10 | This program is distributed in the hope that it will be useful, | |
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | |
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
13 | GNU General Public License for more details. | |
14 | ||
15 | You should have received a copy of the GNU General Public License | |
16 | along with this program. If not, see <http://www.gnu.org/licenses/>. */ | |
17 | ||
18 | /* Written by Paul Eggert. */ | |
19 | ||
e765a388 | 20 | #ifndef _GL_FTOASTR_H |
a451f14b PE |
21 | |
22 | #include "intprops.h" | |
23 | #include <float.h> | |
24 | #include <stddef.h> | |
25 | ||
26 | /* Store into BUF (of size BUFSIZE) an accurate minimal-precision | |
27 | string representation of a floating point number. FLAGS affect the | |
28 | formatting of the number. Pad the output string with spaces as | |
29 | necessary to width WIDTH bytes, in the style of printf. WIDTH must | |
30 | be nonnegative. X is the floating-point number to be converted. | |
31 | ||
32 | Return the number of bytes stored into BUF, not counting the | |
33 | terminating null. However, do not overrun BUF: if BUF is too | |
34 | small, return a fairly tight (but not necessarily exact) upper | |
35 | bound on the value that would have been returned if BUF had been | |
36 | big enough. If SIZE is zero, BUF may be a null pointer. On error | |
37 | (e.g., returned value would exceed INT_MAX), return -1 and set | |
38 | errno. | |
39 | ||
40 | Example: | |
41 | ||
42 | char buf[DBL_BUFSIZE_BOUND]; | |
43 | int r = dtoastr (buf, sizeof buf, 0, 0, 0.1); | |
44 | ||
45 | In the C locale, this sets R to 3 and stores "0.1" into BUF. */ | |
46 | ||
47 | int ftoastr (char *buf, size_t bufsize, int flags, int width, float x); | |
48 | int dtoastr (char *buf, size_t bufsize, int flags, int width, double x); | |
49 | int ldtoastr (char *buf, size_t bufsize, int flags, int width, long double x); | |
50 | ||
51 | /* Flag values for ftoastr etc. These can be ORed together. */ | |
52 | enum | |
53 | { | |
54 | /* Left justify within the width; the default is right justification. */ | |
55 | FTOASTR_LEFT_JUSTIFY = 1, | |
56 | ||
57 | /* Output "+" before positive numbers; the default outputs nothing. */ | |
58 | FTOASTR_ALWAYS_SIGNED = 2, | |
59 | ||
60 | /* Output " " before positive numbers; ignored if | |
caf8a9b2 | 61 | FTOASTR_ALWAYS_SIGNED is also given. */ |
a451f14b PE |
62 | FTOASTR_SPACE_POSITIVE = 4, |
63 | ||
64 | /* Pad with zeros instead of spaces; ignored if FTOASTR_LEFT_JUSTIFY | |
65 | is also given. */ | |
66 | FTOASTR_ZERO_PAD = 8, | |
67 | ||
68 | /* Use 'E' instead of 'e' before the exponent. */ | |
69 | FTOASTR_UPPER_E = 16 | |
70 | }; | |
71 | ||
72 | ||
73 | /* _GL_FLT_PREC_BOUND is an upper bound on the precision needed to | |
74 | represent a float value without losing information. Likewise for | |
75 | _GL_DBL_PREC_BOUND and double, and _GL_LDBL_PREC_BOUND and long double. */ | |
76 | ||
77 | #if FLT_RADIX == 10 /* decimal floating point */ | |
78 | enum { _GL_FLT_PREC_BOUND = FLT_MANT_DIG }; | |
79 | enum { _GL_DBL_PREC_BOUND = DBL_MANT_DIG }; | |
80 | enum { _GL_LDBL_PREC_BOUND = LDBL_MANT_DIG }; | |
81 | #else | |
82 | ||
83 | /* An upper bound on the number of bits needed to represent a single | |
84 | digit in a floating-point fraction. */ | |
85 | # if FLT_RADIX == 2 /* IEEE 754 floating point, VAX floating point, etc. */ | |
86 | # define _GL_FLOAT_DIG_BITS_BOUND 1 | |
87 | # elif FLT_RADIX <= 16 /* IBM hex floating point has FLT_RADIX == 16. */ | |
88 | # define _GL_FLOAT_DIG_BITS_BOUND 4 | |
89 | # else /* no machine is this bad, but let's be complete */ | |
90 | # define _GL_FLOAT_DIG_BITS_BOUND (CHAR_BIT * (int) sizeof (int) - 1) | |
91 | # endif | |
92 | ||
93 | /* An upper bound on the number of decimal digits needed to represent | |
94 | a floating point number accurately, assuming a fraction contains | |
95 | DIG digits. For why the "+ 1" is needed, see "Binary to Decimal | |
96 | Conversion" in David Goldberg's paper "What Every Computer | |
97 | Scientist Should Know About Floating-Point Arithmetic" | |
98 | <http://docs.sun.com/source/806-3568/ncg_goldberg.html>. */ | |
99 | # define _GL_FLOAT_PREC_BOUND(dig) \ | |
100 | (INT_BITS_STRLEN_BOUND ((dig) * _GL_FLOAT_DIG_BITS_BOUND) + 1) | |
101 | ||
102 | enum { _GL_FLT_PREC_BOUND = _GL_FLOAT_PREC_BOUND ( FLT_MANT_DIG) }; | |
103 | enum { _GL_DBL_PREC_BOUND = _GL_FLOAT_PREC_BOUND ( DBL_MANT_DIG) }; | |
104 | enum { _GL_LDBL_PREC_BOUND = _GL_FLOAT_PREC_BOUND (LDBL_MANT_DIG) }; | |
105 | #endif | |
106 | ||
107 | ||
108 | /* Bound on the number of bytes printed for an exponent in the range | |
109 | MIN..MAX, where MIN < 0 < MAX; printf always prints a sign and at | |
110 | least 2 digits. Although the maximum known exponent is 4932 for | |
111 | IEEE 754 binary128, support tight bounds for exponents up to a | |
112 | million, just in case. */ | |
113 | #define _GL_FLOAT_EXPONENT_STRLEN_BOUND(min, max) \ | |
114 | ( -100 < (min) && (max) < 100 ? 3 \ | |
115 | : -1000 < (min) && (max) < 1000 ? 4 \ | |
116 | : -10000 < (min) && (max) < 10000 ? 5 \ | |
117 | : -100000 < (min) && (max) < 100000 ? 6 \ | |
118 | : -1000000 < (min) && (max) < 1000000 ? 7 \ | |
119 | : INT_STRLEN_BOUND (int) /* not a tight bound */) | |
120 | ||
121 | /* A reasonably tight bound on the length of a type-T floating value | |
122 | formatted with ftoastr etc. Room is needed for sign, fraction | |
123 | digits, decimal point, "e", and exponent. POINTLEN should be a | |
124 | reasonably tight bound on the string length of the decimal | |
125 | point. */ | |
126 | #define _GL_FLOAT_STRLEN_BOUND_L(t, pointlen) \ | |
127 | (1 + _GL_##t##_PREC_BOUND + pointlen + 1 \ | |
128 | + _GL_FLOAT_EXPONENT_STRLEN_BOUND (t##_MIN_10_EXP, t##_MAX_10_EXP)) | |
129 | #define FLT_STRLEN_BOUND_L(pointlen) _GL_FLOAT_STRLEN_BOUND_L ( FLT, pointlen) | |
130 | #define DBL_STRLEN_BOUND_L(pointlen) _GL_FLOAT_STRLEN_BOUND_L ( DBL, pointlen) | |
131 | #define LDBL_STRLEN_BOUND_L(pointlen) _GL_FLOAT_STRLEN_BOUND_L (LDBL, pointlen) | |
132 | ||
133 | /* Looser bounds that are locale-independent and are integral constant | |
134 | expressions. */ | |
135 | #define FLT_STRLEN_BOUND FLT_STRLEN_BOUND_L (MB_LEN_MAX) | |
136 | #define DBL_STRLEN_BOUND DBL_STRLEN_BOUND_L (MB_LEN_MAX) | |
137 | #define LDBL_STRLEN_BOUND LDBL_STRLEN_BOUND_L (MB_LEN_MAX) | |
138 | ||
139 | /* Looser, locale-independent bounds that include the trailing null byte. */ | |
140 | #define FLT_BUFSIZE_BOUND ( FLT_STRLEN_BOUND + 1) | |
141 | #define DBL_BUFSIZE_BOUND ( DBL_STRLEN_BOUND + 1) | |
142 | #define LDBL_BUFSIZE_BOUND (LDBL_STRLEN_BOUND + 1) | |
143 | ||
e765a388 | 144 | #endif /* _GL_FTOASTR_H */ |