Index: lib/Support/raw_ostream.cpp =================================================================== --- lib/Support/raw_ostream.cpp +++ lib/Support/raw_ostream.cpp @@ -28,6 +28,9 @@ #include #include #include +#include +#include +#include #include #include @@ -230,8 +233,6 @@ raw_ostream &raw_ostream::operator<<(double N) { #ifdef _WIN32 - // On MSVCRT and compatible, output of %e is incompatible to Posix - // by default. Number of exponent digits should be at least 2. "%+03d" // FIXME: Implement our formatter to here or Support/Format.h! #if defined(__MINGW32__) // FIXME: It should be generic to C++11. @@ -244,29 +245,29 @@ if (fpcl == _FPCLASS_NZ) return *this << "-0.000000e+00"; #endif - - char buf[16]; - unsigned len; - len = format("%e", N).snprint(buf, sizeof(buf)); - if (len <= sizeof(buf) - 2) { - if (len >= 5 && buf[len - 5] == 'e' && buf[len - 3] == '0') { - int cs = buf[len - 4]; - if (cs == '+' || cs == '-') { - int c1 = buf[len - 2]; - int c0 = buf[len - 1]; - if (isdigit(static_cast(c1)) && - isdigit(static_cast(c0))) { - // Trim leading '0': "...e+012" -> "...e+12\0" - buf[len - 3] = c1; - buf[len - 2] = c0; - buf[--len] = 0; - } +#endif + std::ostringstream os; + os.imbue(std::locale("C")); + os << std::scientific << N; + std::string result = os.str(); +#ifdef _WIN32 + // On MSVCRT and compatible, output of %e is incompatible to Posix + // by default. Number of exponent digits should be at least 2. "%+03d" + if (result.size() >= 5 && result[result.size() - 5] == 'e' && + result[result.size() - 3] == '0') { + int cs = result[result.size() - 4]; + if (cs == '+' || cs == '-') { + int c1 = result[result.size() - 2]; + int c0 = result[result.size() - 1]; + if (isdigit(static_cast(c1)) && + isdigit(static_cast(c0))) { + // Trim leading '0': "...e+012" -> "...e+12\0" + result.erase(result.end() - 3); } } - return this->operator<<(buf); } #endif - return this->operator<<(format("%e", N)); + return this->operator<<(result); } void raw_ostream::flush_nonempty() {