Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
63 changes: 55 additions & 8 deletions stl/inc/xlocnum
Original file line number Diff line number Diff line change
Expand Up @@ -1146,6 +1146,45 @@ __PURE_APPDOMAIN_GLOBAL locale::id num_get<_Elem, _InIt>::id;
#pragma clang diagnostic pop
#endif // __clang__

// STRUCT TEMPLATE _Hex_float_precision
template <class _Ty>
struct _Hex_float_precision;

template <>
struct _Hex_float_precision<double> {
// the number of hexits needed to represent (DBL_MANT_DIG - 1) bits after the radix point exactly
static constexpr int value = ((DBL_MANT_DIG - 1) + 3) / 4;
};

template <>
struct _Hex_float_precision<long double> {
// the number of hexits needed to represent (LDBL_MANT_DIG - 1) bits after the radix point exactly
static constexpr int value = ((LDBL_MANT_DIG - 1) + 3) / 4;
};

// FUNCTION TEMPLATE _Float_put_desired_precision
template <class _Ty>
int _Float_put_desired_precision(const streamsize _Precision, const ios_base::fmtflags _Float_flags) {
const bool _Is_hex = _Float_flags == (ios_base::fixed | ios_base::scientific);
if (_Is_hex) {
return _Hex_float_precision<_Ty>::value;
}

if (_Precision > 0) {
return static_cast<int>(_Precision);
} else if (_Precision == 0) {
const bool _Is_default_float = _Float_flags == 0;
if (_Is_default_float) {
return 1;
} else {
return 0;
}
} else {
constexpr int _Default_precision = 6;
return _Default_precision;
}
}

// CLASS TEMPLATE num_put
template <class _Elem, class _OutIt = ostreambuf_iterator<_Elem, char_traits<_Elem>>>
class num_put : public locale::facet { // facet for converting encoded numbers to text
Expand Down Expand Up @@ -1292,10 +1331,14 @@ protected:
_OutIt _Dest, ios_base& _Iosbase, _Elem _Fill, double _Val) const { // put formatted double to _Dest
string _Buf;
char _Fmt[8];
bool _Isfixed = (_Iosbase.flags() & ios_base::floatfield) == ios_base::fixed;
streamsize _Precision = _Iosbase.precision() <= 0 && !_Isfixed ? 6 : _Iosbase.precision(); // desired precision
size_t _Bufsize = static_cast<size_t>(_Precision);
if (_Isfixed && 1e10 < _CSTD fabs(_Val)) { // f or F format
const auto _Float_flags = _Iosbase.flags() & ios_base::floatfield;
const bool _Is_fixed = _Float_flags == ios_base::fixed;
const bool _Is_hex = _Float_flags == (ios_base::fixed | ios_base::scientific);
const streamsize _Precision = _Is_hex ? -1 : _Iosbase.precision(); // precision setting
const int _Desired_precision =
_Float_put_desired_precision<double>(_Precision, _Float_flags); // desired precision
size_t _Bufsize = static_cast<size_t>(_Desired_precision);
if (_Is_fixed && 1e10 < _CSTD fabs(_Val)) { // f or F format
int _Ptwo;
(void) _CSTD frexp(_Val, &_Ptwo);
_Bufsize += _CSTD abs(_Ptwo) * 30103L / 100000L;
Expand All @@ -1312,10 +1355,14 @@ protected:
_OutIt _Dest, ios_base& _Iosbase, _Elem _Fill, long double _Val) const { // put formatted long double to _Dest
string _Buf;
char _Fmt[8];
bool _Isfixed = (_Iosbase.flags() & ios_base::floatfield) == ios_base::fixed;
streamsize _Precision = _Iosbase.precision() <= 0 && !_Isfixed ? 6 : _Iosbase.precision(); // desired precision
size_t _Bufsize = static_cast<size_t>(_Precision);
if (_Isfixed && 1e10 < _CSTD fabsl(_Val)) { // f or F format
const auto _Float_flags = _Iosbase.flags() & ios_base::floatfield;
const bool _Is_fixed = _Float_flags == ios_base::fixed;
const bool _Is_hex = _Float_flags == (ios_base::fixed | ios_base::scientific);
const streamsize _Precision = _Is_hex ? -1 : _Iosbase.precision(); // precision setting
const int _Desired_precision =
_Float_put_desired_precision<long double>(_Precision, _Float_flags); // desired precision
size_t _Bufsize = static_cast<size_t>(_Desired_precision);
if (_Is_fixed && 1e10 < _CSTD fabsl(_Val)) { // f or F format
int _Ptwo;
(void) _CSTD frexpl(_Val, &_Ptwo);
_Bufsize += _CSTD abs(_Ptwo) * 30103L / 100000L;
Expand Down
102 changes: 101 additions & 1 deletion tests/tr1/tests/ostream1/test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -213,9 +213,109 @@ void test_main() { // test basic workings of ostream definitions
outs << STD hexfloat << 2.0;
STD string ans = outs.str();
const char* buf = ans.c_str();
CHECK_STR(buf, "0x1.000p+1");
CHECK_STR(buf, "0x1.0000000000000p+1");
}

outs.precision(0);

outs.str("");
outs << STD defaultfloat << 1.5;
CHECK_STR(outs.str().c_str(), "2");

outs.str("");
outs << STD fixed << 1.0;
CHECK_STR(outs.str().c_str(), "1");

outs.str("");
outs << STD scientific << 2.0;
CHECK_STR(outs.str().c_str(), "2e+00");

outs.str("");
outs << STD hexfloat << 2.0;
CHECK_STR(outs.str().c_str(), "0x1.0000000000000p+1");

outs.precision(-1);

outs.str("");
outs << STD defaultfloat << 1.5;
CHECK_STR(outs.str().c_str(), "1.5");

outs.str("");
outs << STD fixed << 1.0;
CHECK_STR(outs.str().c_str(), "1.000000");

outs.str("");
outs << STD scientific << 2.0;
CHECK_STR(outs.str().c_str(), "2.000000e+00");

outs.str("");
outs << STD hexfloat << 2.0;
CHECK_STR(outs.str().c_str(), "0x1.0000000000000p+1");

outs.precision(-49);
outs.str("");
outs << STD fixed << 1.0;
CHECK_STR(outs.str().c_str(), "1.000000");

outs.precision(3);

outs.str("");
outs << STD defaultfloat << 1.5L;
CHECK_STR(outs.str().c_str(), "1.5");

outs.str("");
outs << STD fixed << 1.0L;
CHECK_STR(outs.str().c_str(), "1.000");

outs.str("");
outs << STD scientific << 2.0L;
CHECK_STR(outs.str().c_str(), "2.000e+00");

outs.str("");
outs << STD hexfloat << 2.0L;
CHECK_STR(outs.str().c_str(), "0x1.0000000000000p+1");

outs.precision(0);

outs.str("");
outs << STD defaultfloat << 1.5L;
CHECK_STR(outs.str().c_str(), "2");

outs.str("");
outs << STD fixed << 1.0L;
CHECK_STR(outs.str().c_str(), "1");

outs.str("");
outs << STD scientific << 2.0L;
CHECK_STR(outs.str().c_str(), "2e+00");

outs.str("");
outs << STD hexfloat << 2.0L;
CHECK_STR(outs.str().c_str(), "0x1.0000000000000p+1");

outs.precision(-1);

outs.str("");
outs << STD defaultfloat << 1.5L;
CHECK_STR(outs.str().c_str(), "1.5");

outs.str("");
outs << STD fixed << 1.0L;
CHECK_STR(outs.str().c_str(), "1.000000");

outs.str("");
outs << STD scientific << 2.0L;
CHECK_STR(outs.str().c_str(), "2.000000e+00");

outs.str("");
outs << STD hexfloat << 2.0L;
CHECK_STR(outs.str().c_str(), "0x1.0000000000000p+1");

outs.precision(-49);
outs.str("");
outs << STD fixed << 1.0L;
CHECK_STR(outs.str().c_str(), "1.000000");

// test Boolx inserter
const Boolx no(0), yes(1);
outs.str("");
Expand Down
102 changes: 101 additions & 1 deletion tests/tr1/tests/ostream2/test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -208,7 +208,107 @@ void test_main() { // test basic workings of ostream definitions
outs << STD hexfloat << 2.0;
STD wstring ans = outs.str();
const wchar_t* buf = ans.c_str();
CHECK_WSTR(buf, L"0x1.000p+1");
CHECK_WSTR(buf, L"0x1.0000000000000p+1");

outs.precision(0);

outs.str(L"");
outs << STD defaultfloat << 1.5;
CHECK_WSTR(outs.str().c_str(), L"2");

outs.str(L"");
outs << STD fixed << 1.0;
CHECK_WSTR(outs.str().c_str(), L"1");

outs.str(L"");
outs << STD scientific << 2.0;
CHECK_WSTR(outs.str().c_str(), L"2e+00");

outs.str(L"");
outs << STD hexfloat << 2.0;
CHECK_WSTR(outs.str().c_str(), L"0x1.0000000000000p+1");

outs.precision(-1);

outs.str(L"");
outs << STD defaultfloat << 1.5;
CHECK_WSTR(outs.str().c_str(), L"1.5");

outs.str(L"");
outs << STD fixed << 1.0;
CHECK_WSTR(outs.str().c_str(), L"1.000000");

outs.str(L"");
outs << STD scientific << 2.0;
CHECK_WSTR(outs.str().c_str(), L"2.000000e+00");

outs.str(L"");
outs << STD hexfloat << 2.0;
CHECK_WSTR(outs.str().c_str(), L"0x1.0000000000000p+1");

outs.precision(-49);
outs.str(L"");
outs << STD fixed << 1.0;
CHECK_WSTR(outs.str().c_str(), L"1.000000");

outs.precision(3);

outs.str(L"");
outs << STD defaultfloat << 1.5L;
CHECK_WSTR(outs.str().c_str(), L"1.5");

outs.str(L"");
outs << STD fixed << 1.0L;
CHECK_WSTR(outs.str().c_str(), L"1.000");

outs.str(L"");
outs << STD scientific << 2.0L;
CHECK_WSTR(outs.str().c_str(), L"2.000e+00");

outs.str(L"");
outs << STD hexfloat << 2.0L;
CHECK_WSTR(outs.str().c_str(), L"0x1.0000000000000p+1");

outs.precision(0);

outs.str(L"");
outs << STD defaultfloat << 1.5L;
CHECK_WSTR(outs.str().c_str(), L"2");

outs.str(L"");
outs << STD fixed << 1.0L;
CHECK_WSTR(outs.str().c_str(), L"1");

outs.str(L"");
outs << STD scientific << 2.0L;
CHECK_WSTR(outs.str().c_str(), L"2e+00");

outs.str(L"");
outs << STD hexfloat << 2.0L;
CHECK_WSTR(outs.str().c_str(), L"0x1.0000000000000p+1");

outs.precision(-1);

outs.str(L"");
outs << STD defaultfloat << 1.5L;
CHECK_WSTR(outs.str().c_str(), L"1.5");

outs.str(L"");
outs << STD fixed << 1.0L;
CHECK_WSTR(outs.str().c_str(), L"1.000000");

outs.str(L"");
outs << STD scientific << 2.0L;
CHECK_WSTR(outs.str().c_str(), L"2.000000e+00");

outs.str(L"");
outs << STD hexfloat << 2.0L;
CHECK_WSTR(outs.str().c_str(), L"0x1.0000000000000p+1");

outs.precision(-49);
outs.str(L"");
outs << STD fixed << 1.0L;
CHECK_WSTR(outs.str().c_str(), L"1.000000");

// test Boolx inserter
const Boolx no(0), yes(1);
Expand Down