Annotation of GNUtools/libg++/libio/outfloat.c, revision 1.1.1.1

1.1       root        1: /* 
                      2: Copyright (C) 1993 Free Software Foundation
                      3: 
                      4: This file is part of the GNU IO Library.  This library is free
                      5: software; you can redistribute it and/or modify it under the
                      6: terms of the GNU General Public License as published by the
                      7: Free Software Foundation; either version 2, or (at your option)
                      8: any later version.
                      9: 
                     10: This library 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 GNU CC; see the file COPYING.  If not, write to
                     17: the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
                     18: 
                     19: As a special exception, if you link this library with files
                     20: compiled with a GNU compiler to produce an executable, this does not cause
                     21: the resulting executable to be covered by the GNU General Public License.
                     22: This exception does not however invalidate any other reasons why
                     23: the executable file might be covered by the GNU General Public License. */
                     24: 
                     25: #include "libioP.h"
                     26: 
                     27: /* Format floating-point number and print them.
                     28:    Return number of chars printed, or EOF on error.
                     29: 
                     30:    sign_mode == '+' : print "-" or "+"
                     31:    sign_mode == ' ' : print "-" or " "
                     32:    sign_mode == '\0' : print "-' or ""
                     33: */
                     34: 
                     35: int _IO_outfloat(value, sb, type, width, precision, flags,
                     36:               sign_mode, fill)
                     37:      double value;
                     38:      _IO_FILE *sb;
                     39:      int type;
                     40:      int width;
                     41:      int precision;
                     42:      int flags;
                     43:      int sign_mode;
                     44:      int fill;
                     45: {
                     46:   int count = 0;
                     47: #define PUT(x) do {if (_IO_putc(x, sb) < 0) goto error; count++;} while (0)
                     48: #define PUTN(p, n) \
                     49:   do {int _n=n; count+=_n; if (_IO_sputn(sb, p,_n) != _n) goto error;} while(0)
                     50: #define PADN(fill, n) \
                     51:   do {int _n = n; count+=_n; if (_IO_padn(sb, fill, _n) != _n) goto error;} while (0)
                     52:   int pad_kind = flags & (_IO_LEFT|_IO_RIGHT|_IO_INTERNAL);
                     53:   int skip_zeroes = 0;
                     54:   int show_dot = (flags & _IO_SHOWPOINT) != 0;
                     55:   int decpt;
                     56:   int sign;
                     57:   int mode;
                     58:   int exponent_size;
                     59:   int print_sign;
                     60:   int trailing_zeroes, useful_digits;
                     61:   int padding, unpadded_width;
                     62:   char *p;
                     63:   char *exponent_start;
                     64:   register int i;
                     65: #define EBUF_SIZE 12
                     66: #define EBUF_END &ebuf[EBUF_SIZE]
                     67:   char ebuf[EBUF_SIZE];
                     68:   char *end;
                     69:   int exp = 0;
                     70:   switch (type)
                     71:     {
                     72:     case 'f':
                     73:       mode = 3;
                     74:       break;
                     75:     case 'e':
                     76:     case 'E':
                     77:       exp = type;
                     78:       mode = 2;
                     79:       if (precision != 999)
                     80:        precision++;  /* Add one to include digit before decimal point. */
                     81:       break;
                     82:     case 'g':
                     83:     case 'G':
                     84:       exp = type == 'g' ? 'e' : 'E';
                     85:       if (precision == 0) precision = 1;
                     86:       if (!(flags & _IO_SHOWPOINT))
                     87:        skip_zeroes = 1;
                     88:       type = 'g';
                     89:       mode = 2;
                     90:       break;
                     91:     }
                     92:   /* Do the actual convension */
                     93:   if (precision == 999 && mode != 3)
                     94:     mode = 0;
                     95:   p = _IO_dtoa(value, mode, precision, &decpt, &sign, &end);
                     96:   useful_digits = end-p;
                     97:   exponent_start = EBUF_END;
                     98:   if (mode == 0)
                     99:     precision = useful_digits;
                    100:   /* Check if we need to emit an exponent. */
                    101:   if (mode != 3 && decpt != 9999)
                    102:     {
                    103:       i = decpt - 1;
                    104:       if ((type != 'g' && type != 'F') || i < -4 || i >= precision)
                    105:        {
                    106:          /* Print the exponent into ebuf.
                    107:             We write ebuf in reverse order (right-to-left). */
                    108:          char sign;
                    109:          if (i >= 0)
                    110:            sign = '+';
                    111:          else
                    112:            sign = '-', i = -i;
                    113:          /* Note: ANSI requires at least 2 exponent digits. */
                    114:          do {
                    115:            *--exponent_start = (i % 10) + '0';
                    116:            i /= 10;
                    117:          } while (i >= 10);
                    118:          *--exponent_start = i + '0';
                    119:          *--exponent_start = sign;
                    120:          *--exponent_start = exp;
                    121:        }
                    122:     }
                    123:   exponent_size = EBUF_END - exponent_start;
                    124:   if (mode == 1)
                    125:     precision = 1;
                    126:   /* If we print an exponent, always show just one digit before point. */
                    127:   if (exponent_size)
                    128:     decpt = 1;
                    129:   if (decpt == 9999)
                    130:     { /* Infinity or NaN */
                    131:       decpt = useful_digits;
                    132:       precision = 0;
                    133:       show_dot = 0;
                    134:     }
                    135:   
                    136:   /* dtoa truncates trailing zeroes.  Set the variable trailing_zeroes to
                    137:      the number of 0's we have to add (after the decimal point). */
                    138:   if (skip_zeroes)
                    139:     trailing_zeroes = 0;
                    140:   else if (type == 'f')
                    141:     trailing_zeroes = useful_digits <= decpt ? precision
                    142:       : precision-(useful_digits-decpt);
                    143:   else if (exponent_size) /* 'e' 'E' or 'g' format using exponential notation*/
                    144:     trailing_zeroes = precision - useful_digits;
                    145:   else /* 'g' format not using exponential notation. */
                    146:     trailing_zeroes = useful_digits <= decpt ? precision - decpt
                    147:       : precision-useful_digits;
                    148:   if (trailing_zeroes < 0) trailing_zeroes = 0;
                    149:   
                    150:   if (trailing_zeroes != 0 || useful_digits > decpt)
                    151:     show_dot = 1;
                    152:   if (sign_mode == 0)
                    153:     print_sign = sign ? '-' : 0;
                    154:   else if (sign_mode == '+')
                    155:     print_sign = sign ? '-' : '+';
                    156:   else /* if (sign_mode == ' ') */
                    157:     print_sign = sign ? '-' : ' ';
                    158:   
                    159:   /* Calculate the width (before padding). */
                    160:   unpadded_width =
                    161:     (print_sign != 0) + trailing_zeroes + exponent_size + show_dot
                    162:       + useful_digits
                    163:        + (decpt > useful_digits ? decpt - useful_digits
                    164:           : decpt > 0 ? 0 : 1 - decpt);
                    165:   
                    166:   padding = width > unpadded_width ? width - unpadded_width : 0;
                    167:   if (padding > 0 && pad_kind != _IO_LEFT && pad_kind != _IO_INTERNAL)
                    168:     PADN(fill, padding); /* Default (right) adjust */
                    169:   if (print_sign)
                    170:     PUT(print_sign);
                    171:   if (pad_kind == _IO_INTERNAL && padding > 0)
                    172:     PADN(fill, padding);
                    173:   if (decpt > 0)
                    174:     {
                    175:       if (useful_digits >= decpt)
                    176:        PUTN(p, decpt);
                    177:       else
                    178:        {
                    179:          PUTN(p, useful_digits);
                    180:          PADN('0', decpt-useful_digits);
                    181:        }
                    182:       if (show_dot)
                    183:        {
                    184:          PUT('.');
                    185:          /* Print digits after the decimal point. */
                    186:          if (useful_digits > decpt)
                    187:            PUTN(p + decpt, useful_digits-decpt);
                    188:        }
                    189:     }
                    190:   else
                    191:     {
                    192:       PUT('0');
                    193:       if (show_dot)
                    194:        {
                    195:          PUT('.');
                    196:          PADN('0', -decpt);
                    197:          /* Print digits after the decimal point. */
                    198:          PUTN(p, useful_digits);
                    199:        }
                    200:     }
                    201:   PADN('0', trailing_zeroes);
                    202:   if (exponent_size)
                    203:     PUTN(exponent_start, exponent_size);
                    204:   if (pad_kind == _IO_LEFT && padding > 0) /* Left adjustment*/
                    205:     PADN(fill, padding);
                    206:   return count;
                    207:  error:
                    208:   return EOF;
                    209: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.