Annotation of GNUtools/libg++/libio/outfloat.c, revision 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.