root/maint/gnulib/lib/ftoastr.h

/* [previous][next][first][last][top][bottom][index][help] */

INCLUDED FROM


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

/* [previous][next][first][last][top][bottom][index][help] */