⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 outfloat.c

📁 早期freebsd实现
💻 C
字号:
//    This is part of the iostream library, providing input/output for C++.//    Copyright (C) 1992 Per Bothner.////    This library is free software; you can redistribute it and/or//    modify it under the terms of the GNU Library General Public//    License as published by the Free Software Foundation; either//    version 2 of the License, or (at your option) any later version.////    This library is distributed in the hope that it will be useful,//    but WITHOUT ANY WARRANTY; without even the implied warranty of//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU//    Library General Public License for more details.////    You should have received a copy of the GNU Library General Public//    License along with this library; if not, write to the Free//    Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.#include "ioprivate.h"// Format floating-point number and print them.// Return number of chars printed, or EOF on error.// sign_mode == '+' : print "-" or "+"// sign_mode == ' ' : print "-" or " "// sign_mode == '\0' : print "-' or ""int __outfloat(double value, streambuf *sb, char type,	       int width, int precision, ios::fmtflags flags,	       char sign_mode, char fill){    int count = 0;#define PUT(x) do {if (sb->sputc(x) < 0) goto error; count++;} while (0)#define PUTN(p, n) \  do {int _n=n; count+=_n; if (sb->sputn(p,_n) != _n) goto error;} while(0)#define PADN(fill, n) \  do {int _n = n; count+=_n; if (sb->padn(fill, _n) < 0) goto error;} while (0)    ios::fmtflags pad_kind = flags & (ios::left|ios::right|ios::internal);    int skip_zeroes = 0;    int show_dot = (flags & ios::showpoint) != 0;    int decpt;    int sign;    int mode;#define EBUF_SIZE 12#define EBUF_END &ebuf[EBUF_SIZE]    char ebuf[EBUF_SIZE];    char *end;    int exp = 0;    switch (type) {      case 'f':	mode = 3;	break;      case 'F':	exp = 'e';	mode = 0;	skip_zeroes = 1;	type = 'g';	break;      case 'e':	exp = 'e';	mode = 2;	precision++;  // Add one to include digit before decimal point.	break;      case 'E':	exp = 'E';	mode = 2;	precision++;  // Add one to include digit before decimal point.	break;      case 'g':      case 'G':	exp = type == 'g' ? 'e' : 'E';	if (precision == 0) precision = 1;	if (!(flags & ios::showpoint))	    skip_zeroes = 1;	type = 'g';	mode = 2;	break;    }    /* Do the actual convension */    char *p = dtoa(value, mode, precision, &decpt, &sign, &end);    register int i;    int useful_digits = end-p;    char *exponent_start = EBUF_END;    // Check if we need to emit an exponent.    if (mode != 3 && decpt != 9999) {	i = decpt - 1;	if ((type != 'g' && type != 'F') || i < -4 || i >= precision) {	    // Print the exponent into ebuf.	    // We write ebuf in reverse order (right-to-left).	    char sign;	    if (i >= 0)		sign = '+';	    else		sign = '-', i = -i;	    /* Note: ANSI requires at least 2 exponent digits. */	    do {		*--exponent_start = (i % 10) + '0';		i /= 10;	    } while (i >= 10);	    *--exponent_start = i + '0';	    *--exponent_start = sign;	    *--exponent_start = exp;	}    }    int exponent_size = EBUF_END - exponent_start;    if (mode == 1)	precision = 1;    /* If we print an exponent, always show just one digit before point. */    if (exponent_size)	decpt = 1;    if (decpt == 9999) { // Infinity or NaN	decpt = useful_digits;	precision = 0;	show_dot = 0;    }   // dtoa truncates trailing zeroes.  Set the variable trailing_zeroes to   // the number of 0's we have to add (after the decimal point).   int trailing_zeroes = 0;   if (skip_zeroes)       trailing_zeroes = 0;   else if (type == 'f')       trailing_zeroes = useful_digits <= decpt ? precision	   : precision-(useful_digits-decpt);   else if (exponent_size) // 'e' 'E' or 'g' format using exponential notation.       trailing_zeroes = precision - useful_digits;   else // 'g' format not using exponential notation.       trailing_zeroes = useful_digits <= decpt ? precision - decpt	   : precision-useful_digits;    if (trailing_zeroes < 0) trailing_zeroes = 0;    if (trailing_zeroes != 0 || useful_digits > decpt)	show_dot = 1;    int print_sign;    if (sign_mode == 0)	print_sign = sign ? '-' : 0;    else if (sign_mode == '+')	print_sign = sign ? '-' : '+';    else /* if (sign_mode == ' ') */	print_sign = sign ? '-' : ' ';        // Calculate the width (before padding).    int unpadded_width =	(print_sign != 0) + trailing_zeroes + exponent_size + show_dot	    + useful_digits + (decpt > 0 ? 0 : 1 - decpt);    int padding = width > unpadded_width ? width - unpadded_width : 0;    if (padding > 0	&& pad_kind != (ios::fmtflags)ios::left	&& pad_kind != (ios::fmtflags)ios::internal) // Default (right) adjust.	PADN(fill, padding);    if (print_sign)	PUT(print_sign);    if (pad_kind == (ios::fmtflags)ios::internal && padding > 0)	PADN(fill, padding);    if (decpt > 0) {	if (useful_digits >= decpt)	    PUTN(p, decpt);	else {	    PUTN(p, useful_digits);	    PADN('0', decpt-useful_digits);	}	if (show_dot) {	    PUT('.');	    // Print digits after the decimal point.	    if (useful_digits > decpt)		PUTN(p + decpt, useful_digits-decpt);	}    }    else {	PUT('0');	if (show_dot) {	    PUT('.');	    PADN('0', -decpt);	    // Print digits after the decimal point.	    PUTN(p, useful_digits);	}    }    PADN('0', trailing_zeroes);    if (exponent_size)	PUTN(exponent_start, exponent_size);    if (pad_kind == (ios::fmtflags)ios::left && padding > 0) // Left adjustment	PADN(fill, padding);    return count;  error:    return EOF;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -