Start fixing cursor motion around invisible text.
[emacs.git] / lib / ftoastr.h
blob6264952e8e97e1563afd351c038af3823e777cf6
1 /* floating point to accurate string
3 Copyright (C) 2010-2011 Free Software Foundation, Inc.
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.
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.
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/>. */
18 /* Written by Paul Eggert. */
20 #ifndef _GL_FTOASTR_H
22 #include "intprops.h"
23 #include <float.h>
24 #include <stddef.h>
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.
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.
40 Example:
42 char buf[DBL_BUFSIZE_BOUND];
43 int r = dtoastr (buf, sizeof buf, 0, 0, 0.1);
45 In the C locale, this sets R to 3 and stores "0.1" into BUF. */
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);
51 /* Flag values for ftoastr etc. These can be ORed together. */
52 enum
54 /* Left justify within the width; the default is right justification. */
55 FTOASTR_LEFT_JUSTIFY = 1,
57 /* Output "+" before positive numbers; the default outputs nothing. */
58 FTOASTR_ALWAYS_SIGNED = 2,
60 /* Output " " before positive numbers; ignored if
61 FTOASTER_ALWAYS_SIGNED is also given. */
62 FTOASTR_SPACE_POSITIVE = 4,
64 /* Pad with zeros instead of spaces; ignored if FTOASTR_LEFT_JUSTIFY
65 is also given. */
66 FTOASTR_ZERO_PAD = 8,
68 /* Use 'E' instead of 'e' before the exponent. */
69 FTOASTR_UPPER_E = 16
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. */
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
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
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)
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
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 */)
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)
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)
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)
144 #endif /* _GL_FTOASTR_H */