📄 num_put_float.cpp
字号:
} else { // NaN
inf_or_nan = nan;
if (_Stl_is_neg_nan(x))
buf += '-';
else if (flags & ios_base::showpos)
buf += '+';
}
buf += inf_or_nan[flags & ios_base::uppercase ? 1 : 0];
}
template <class max_double_type>
static inline size_t __format_float( __iostring &buf, const char * bp,
int decpt, int sign, max_double_type x,
ios_base::fmtflags flags,
int precision, bool islong)
{
size_t __group_pos = 0;
// Output of infinities and NANs does not depend on the format flags
if (_Stl_is_nan_or_inf((double)x)) { // Infinity or NaN
__format_nan_or_inf(buf, (double)x, flags);
} else { // representable number
switch (flags & ios_base::floatfield) {
case ios_base::scientific:
__group_pos = __format_float_scientific( buf, bp, decpt, sign, x == 0.0,
flags, precision, islong);
break;
case ios_base::fixed:
__group_pos = __format_float_fixed( buf, bp, decpt, sign, true,
flags, precision, islong);
break;
default: // g format
// establish default precision
if (flags & ios_base::showpoint || precision > 0) {
if (precision == 0) precision = 1;
} else
precision = 6;
// reset exponent if value is zero
if (x == 0)
decpt = 1;
int kk = precision;
if (!(flags & ios_base::showpoint)) {
size_t n = strlen(bp);
if (n < (size_t)kk)
kk = (int)n;
while (kk >= 1 && bp[kk-1] == '0')
--kk;
}
if (decpt < -3 || decpt > precision) {
precision = kk - 1;
__group_pos = __format_float_scientific( buf, bp, decpt, sign, x == 0,
flags, precision, islong);
} else {
precision = kk - decpt;
__group_pos = __format_float_fixed( buf, bp, decpt, sign, true,
flags, precision, islong);
}
break;
} /* switch */
} /* else is_nan_or_inf */
return __group_pos;
}
#else /* USE_SPRINTF_INSTEAD */
struct GroupPos {
bool operator () (char __c) const {
return __c == '.' ||
__c == 'e' || __c == 'E';
}
};
// Creates a format string for sprintf()
static int __fill_fmtbuf(char* fmtbuf, ios_base::fmtflags flags, char long_modifier) {
fmtbuf[0] = '%';
int i = 1;
if (flags & ios_base::showpos)
fmtbuf[i++] = '+';
if (flags & ios_base::showpoint)
fmtbuf[i++] = '#';
fmtbuf[i++] = '.';
fmtbuf[i++] = '*';
if (long_modifier)
fmtbuf[i++] = long_modifier;
switch (flags & ios_base::floatfield)
{
case ios_base::scientific:
fmtbuf[i++] = (flags & ios_base::uppercase) ? 'E' : 'e';
break;
case ios_base::fixed:
# if defined (__FreeBSD__)
fmtbuf[i++] = 'f';
# else
fmtbuf[i++] = (flags & ios_base::uppercase) ? 'F' : 'f';
# endif
break;
default:
fmtbuf[i++] = (flags & ios_base::uppercase) ? 'G' : 'g';
break;
}
fmtbuf[i] = 0;
return i;
}
#endif /* USE_SPRINTF_INSTEAD */
size_t _STLP_CALL
__write_float(__iostring &buf, ios_base::fmtflags flags, int precision,
double x) {
#if defined (USE_SPRINTF_INSTEAD)
/* If we want 'abitrary' precision, we should use 'abitrary' buffer size
* below. - ptr
*/
char static_buf[128];
// char *static_buf = new char [128+precision];
char fmtbuf[32];
__fill_fmtbuf(fmtbuf, flags, 0);
// snprintf(static_buf, 128+precision, fmtbuf, precision, x);
# if !defined (N_PLAT_NLM)
snprintf(_STLP_ARRAY_AND_SIZE(static_buf), fmtbuf, precision, x);
# else
sprintf(static_buf, fmtbuf, precision, x);
# endif
buf = static_buf;
// delete [] static_buf;
return find_if(buf.begin(), buf.end(), GroupPos()) - buf.begin();
#else
# if !defined (_STLP_CVT_DONT_NEED_BUF)
char cvtbuf[NDIG + 2];
# endif
char * bp;
int decpt, sign;
switch (flags & ios_base::floatfield) {
case ios_base::fixed:
bp = _Stl_fcvtR(x, (min) (precision, MAXFCVT), &decpt, &sign _STLP_CVT_BUFFER(cvtbuf));
break;
case ios_base::scientific :
bp = _Stl_ecvtR(x, (min) (precision + 1, MAXECVT), &decpt, &sign _STLP_CVT_BUFFER(cvtbuf));
break;
default :
bp = _Stl_ecvtR(x, (min) (precision, MAXECVT), &decpt, &sign _STLP_CVT_BUFFER(cvtbuf));
break;
}
return __format_float(buf, bp, decpt, sign, x, flags, precision, false);
#endif
}
#if !defined (_STLP_NO_LONG_DOUBLE)
size_t _STLP_CALL
__write_float(__iostring &buf, ios_base::fmtflags flags, int precision,
long double x) {
# if defined (USE_SPRINTF_INSTEAD)
/* If we want 'abitrary' precision, we should use 'abitrary' buffer size
* below. - ptr
*/
char static_buf[128];
// char *static_buf = new char [128+precision];
char fmtbuf[64];
int i = __fill_fmtbuf(fmtbuf, flags, 'L');
// snprintf(static_buf, 128+precision, fmtbuf, precision, x);
# if !defined (N_PLAT_NLM)
snprintf(_STLP_ARRAY_AND_SIZE(static_buf), fmtbuf, precision, x);
# else
sprintf(static_buf, fmtbuf, precision, x);
# endif
// we should be able to return buf + sprintf(), but we do not trust'em...
buf = static_buf;
// delete [] static_buf;
return find_if(buf.begin(), buf.end(), GroupPos()) - buf.begin();
# else
# if !defined (_STLP_CVT_DONT_NEED_BUF)
char cvtbuf[NDIG + 2];
# endif
char * bp;
int decpt, sign;
switch (flags & ios_base::floatfield) {
case ios_base::fixed:
bp = _Stl_qfcvtR(x, (min) (precision, MAXFCVT), &decpt, &sign _STLP_CVT_BUFFER(cvtbuf));
break;
case ios_base::scientific:
bp = _Stl_qecvtR(x, (min) (precision + 1, MAXECVT), &decpt, &sign _STLP_CVT_BUFFER(cvtbuf));
break;
default :
bp = _Stl_qecvtR(x, (min) (precision, MAXECVT), &decpt, &sign _STLP_CVT_BUFFER(cvtbuf));
break;
}
return __format_float(buf, bp, decpt, sign, x, flags, precision, true);
# endif /* USE_SPRINTF_INSTEAD */
}
#endif /* _STLP_NO_LONG_DOUBLE */
void _STLP_CALL __get_floor_digits(__iostring &out, _STLP_LONGEST_FLOAT_TYPE __x) {
#if defined (USE_SPRINTF_INSTEAD)
char cvtbuf[128];
# if !defined (_STLP_NO_LONG_DOUBLE)
# if !defined (N_PLAT_NLM)
snprintf(_STLP_ARRAY_AND_SIZE(cvtbuf), "%Lf", __x); // check for 1234.56!
# else
sprintf(cvtbuf, "%Lf", __x); // check for 1234.56!
# endif
# else
snprintf(_STLP_ARRAY_AND_SIZE(cvtbuf), "%f", __x); // check for 1234.56!
# endif
char *p = strchr( cvtbuf, '.' );
if ( p == 0 ) {
out.append( cvtbuf );
} else {
out.append( cvtbuf, p );
}
#else
# if !defined (_STLP_CVT_DONT_NEED_BUF)
char cvtbuf[NDIG + 2];
# endif
char * bp;
int decpt, sign;
# if !defined (_STLP_NO_LONG_DOUBLE)
bp = _Stl_qfcvtR(__x, 0, &decpt, &sign _STLP_CVT_BUFFER(cvtbuf));
# else
bp = _Stl_fcvtR(__x, 0, &decpt, &sign _STLP_CVT_BUFFER(cvtbuf));
# endif
if (sign) {
out += '-';
}
out.append(bp, bp + decpt);
#endif // USE_PRINTF_INSTEAD
}
#if !defined (_STLP_NO_WCHAR_T)
void _STLP_CALL __convert_float_buffer( __iostring const& str, __iowstring &out,
const ctype<wchar_t>& ct, wchar_t dot, bool __check_dot)
{
string::const_iterator str_ite(str.begin()), str_end(str.end());
//First loop, check the dot char
if (__check_dot) {
while (str_ite != str_end) {
if (*str_ite != '.') {
out += ct.widen(*str_ite++);
} else {
out += dot;
break;
}
}
} else {
if (str_ite != str_end) {
out += ct.widen(*str_ite);
}
}
if (str_ite != str_end) {
//Second loop, dot has been found, no check anymore
while (++str_ite != str_end) {
out += ct.widen(*str_ite);
}
}
}
#endif
void _STLP_CALL
__adjust_float_buffer(__iostring &str, char dot) {
if ('.' != dot) {
size_t __dot_pos = str.find('.');
if (__dot_pos != string::npos) {
str[__dot_pos] = dot;
}
}
}
_STLP_MOVE_TO_STD_NAMESPACE
_STLP_END_NAMESPACE
// Local Variables:
// mode:C++
// End:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -