(linenum→info "unix/slp.c:2238")

glibc/2.7/misc/efgcvt.c

    1: /* Compatibility functions for floating point formatting.
    2:    Copyright (C) 1995, 1996, 1997, 1999, 2002, 2006
    3:    Free Software Foundation, Inc.
    4:    This file is part of the GNU C Library.
    5: 
    6:    The GNU C Library is free software; you can redistribute it and/or
    7:    modify it under the terms of the GNU Lesser General Public
    8:    License as published by the Free Software Foundation; either
    9:    version 2.1 of the License, or (at your option) any later version.
   10: 
   11:    The GNU C Library is distributed in the hope that it will be useful,
   12:    but WITHOUT ANY WARRANTY; without even the implied warranty of
   13:    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   14:    Lesser General Public License for more details.
   15: 
   16:    You should have received a copy of the GNU Lesser General Public
   17:    License along with the GNU C Library; if not, write to the Free
   18:    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
   19:    02111-1307 USA.  */
   20: 
   21: #include <math.h>
   22: #include <stdio.h>
   23: #include <stdlib.h>
   24: #include <sys/param.h>
   25: #include <float.h>
   26: #include <bits/libc-lock.h>
   27: #include <math_ldbl_opt.h>
   28: 
   29: #ifndef FLOAT_TYPE
   30: # define FLOAT_TYPE double
   31: # define FUNC_PREFIX
   32: # define FLOAT_FMT_FLAG
   33: /* Actually we have to write (DBL_DIG + log10 (DBL_MAX_10_EXP)) but we
   34:    don't have log10 available in the preprocessor.  */
   35: # define MAXDIG (NDIGIT_MAX + 3)
   36: # define FCVT_MAXDIG (DBL_MAX_10_EXP + MAXDIG)
   37: # if DBL_MANT_DIG == 53
   38: #  define NDIGIT_MAX 17
   39: # elif DBL_MANT_DIG == 24
   40: #  define NDIGIT_MAX 9
   41: # elif DBL_MANT_DIG == 56
   42: #  define NDIGIT_MAX 18
   43: # else
   44: /* See IEEE 854 5.6, table 2 for this formula.  Unfortunately we need a
   45:    compile time constant here, so we cannot use it.  */
   46: #  error "NDIGIT_MAX must be precomputed"
   47: #  define NDIGIT_MAX (lrint (ceil (M_LN2 / M_LN10 * DBL_MANT_DIG + 1.0)))
   48: # endif
   49: #else
   50: # define LONG_DOUBLE_CVT
   51: #endif
   52: 
   53: #define APPEND(a, b) APPEND2 (a, b)
   54: #define APPEND2(a, b) a##b
   55: #define __APPEND(a, b) __APPEND2 (a, b)
   56: #define __APPEND2(a, b) __##a##b
   57: 
   58: 
   59: #define FCVT_BUFFER APPEND (FUNC_PREFIX, fcvt_buffer)
   60: #define FCVT_BUFPTR APPEND (FUNC_PREFIX, fcvt_bufptr)
   61: #define ECVT_BUFFER APPEND (FUNC_PREFIX, ecvt_buffer)
   62: 
   63: 
   64: static char FCVT_BUFFER[MAXDIG];
   65: static char ECVT_BUFFER[MAXDIG];
   66: libc_freeres_ptr (static char *FCVT_BUFPTR);
   67: 
   68: char *
   69: __APPEND (FUNC_PREFIX, fcvt) (value, ndigit, decpt, sign)
   70:      FLOAT_TYPE value;
   71:      int ndigit, *decpt, *sign;
   72: {
   73:   if (FCVT_BUFPTR == NULL)
   74:     {
   75:       if (__APPEND (FUNC_PREFIX, fcvt_r) (value, ndigit, decpt, sign,
   76:                                           FCVT_BUFFER, MAXDIG) != -1)
   77:         return FCVT_BUFFER;
   78: 
   79:       FCVT_BUFPTR = (char *) malloc (FCVT_MAXDIG);
   80:       if (FCVT_BUFPTR == NULL)
   81:         return FCVT_BUFFER;
   82:     }
   83: 
   84:   (void) __APPEND (FUNC_PREFIX, fcvt_r) (value, ndigit, decpt, sign,
   85:                                          FCVT_BUFPTR, FCVT_MAXDIG);
   86: 
   87:   return FCVT_BUFPTR;
   88: }
   89: 
   90: 
   91: char *
   92: __APPEND (FUNC_PREFIX, ecvt) (value, ndigit, decpt, sign)
   93:      FLOAT_TYPE value;
   94:      int ndigit, *decpt, *sign;
   95: {
   96:   (void) __APPEND (FUNC_PREFIX, ecvt_r) (value, ndigit, decpt, sign,
   97:                                          ECVT_BUFFER, MAXDIG);
   98: 
   99:   return ECVT_BUFFER;
  100: }
  101: 
  102: char *
  103: __APPEND (FUNC_PREFIX, gcvt) (value, ndigit, buf)
  104:      FLOAT_TYPE value;
  105:      int ndigit;
  106:      char *buf;
  107: {
  108:   sprintf (buf, "%.*" FLOAT_FMT_FLAG "g", MIN (ndigit, NDIGIT_MAX), value);
  109:   return buf;
  110: }
  111: 
  112: #if LONG_DOUBLE_COMPAT (libc, GLIBC_2_0)
  113: # ifdef LONG_DOUBLE_CVT
  114: #  define cvt_symbol(symbol) \
  115:   cvt_symbol_1 (libc, __APPEND (FUNC_PREFIX, symbol), \
  116:               APPEND (FUNC_PREFIX, symbol), GLIBC_2_4)
  117: #  define cvt_symbol_1(lib, local, symbol, version) \
  118:     versioned_symbol (lib, local, symbol, version)
  119: # else
  120: #  define cvt_symbol(symbol) \
  121:   cvt_symbol_1 (libc, __APPEND (FUNC_PREFIX, symbol), \
  122:               APPEND (q, symbol), GLIBC_2_0); \
  123:   strong_alias (__APPEND (FUNC_PREFIX, symbol), APPEND (FUNC_PREFIX, symbol))
  124: #  define cvt_symbol_1(lib, local, symbol, version) \
  125:   compat_symbol (lib, local, symbol, version)
  126: # endif
  127: #else
  128: # define cvt_symbol(symbol) \
  129:   strong_alias (__APPEND (FUNC_PREFIX, symbol), APPEND (FUNC_PREFIX, symbol))
  130: #endif
  131: cvt_symbol(fcvt);
  132: cvt_symbol(ecvt);
  133: cvt_symbol(gcvt);
Syntax (Markdown)