控制科学计数法的指数位数
默认情况下,用科学计数法表示实数,输出的指数位数为3。如何控制使其只输出2位指数位?VC6下如何?VC2005又如何?
在VC2005下,运行库提供一个函数_set_output_format可以控制printf输出的实数的指数位,要输
出2位指数位需要这样设置:
unsigned int old_exponent_format = _set_output_format(_TWO_DIGIT_EXPONENT);
使用完恢复原来设置:
_set_output_format(old_exponent_format);
在VC6中没有此函数,相同功能的函数我也没有发现。
在C++标准库中的stream中,我也没有找到这样的格式控制符。为了在VC6下完成此功能,最后只能
选择曲线救国的道路了——删除一个0。
1、对于printf这样的输出解决方法:
void
EraseZeroPlus(std::
string
&
str,
string
::size_type pos)
{
string::size_type pos1= str.find("E+", pos);
if(pos1 == string::npos)
return;
pos1 +=2;
str.erase(pos1, 1);
EraseZeroPlus(str, pos1);
}
void EraseZeroMinus(std:: string & str, string ::size_type pos)
{
string::size_type pos1= str.find("E-", pos);
if(pos1 == string::npos)
return;
pos1 +=2;
str.erase(pos1, 1);
EraseZeroMinus(str, pos1);
}
void EraseZero( char * szBuf, FILE * pFile)
{
string str(szBuf);
EraseZeroPlus(str, 0);
EraseZeroMinus(str, 0);
fputs(str.c_str(), pFile);
}
{
string::size_type pos1= str.find("E+", pos);
if(pos1 == string::npos)
return;
pos1 +=2;
str.erase(pos1, 1);
EraseZeroPlus(str, pos1);
}
void EraseZeroMinus(std:: string & str, string ::size_type pos)
{
string::size_type pos1= str.find("E-", pos);
if(pos1 == string::npos)
return;
pos1 +=2;
str.erase(pos1, 1);
EraseZeroMinus(str, pos1);
}
void EraseZero( char * szBuf, FILE * pFile)
{
string str(szBuf);
EraseZeroPlus(str, 0);
EraseZeroMinus(str, 0);
fputs(str.c_str(), pFile);
}
2、对于stream这样的输出解决方法:
这里只是考虑输出文件的情况。
.h file
template
<
class
_E,
class
_Tr
=
std::char_traits
<
_E
>
>
class my_ofstream : public std::basic_ofstream < _E, _Tr >
{
public:
my_ofstream(){m_nPrecision = 5}
explicit my_ofstream(const char *_S,
ios_base::openmode _M = out | trunc)
: std::basic_ofstream<_E, _Tr>(_S, _M)
{
m_nPrecision = 5;
}
void set_precision(int nPre)
{
m_nPrecision = nPre;
}
int get_precision(void)
{
return m_nPrecision;
}
virtual ~my_ofstream(){}
private:
int m_nPrecision;
} ;
typedef my_ofstream < char > myofstream;
// overload operator for double and float value
myofstream & operator << (myofstream & strm, float value);
myofstream & operator << (myofstream & strm, double value);
class my_ofstream : public std::basic_ofstream < _E, _Tr >
{
public:
my_ofstream(){m_nPrecision = 5}
explicit my_ofstream(const char *_S,
ios_base::openmode _M = out | trunc)
: std::basic_ofstream<_E, _Tr>(_S, _M)
{
m_nPrecision = 5;
}
void set_precision(int nPre)
{
m_nPrecision = nPre;
}
int get_precision(void)
{
return m_nPrecision;
}
virtual ~my_ofstream(){}
private:
int m_nPrecision;
} ;
typedef my_ofstream < char > myofstream;
// overload operator for double and float value
myofstream & operator << (myofstream & strm, float value);
myofstream & operator << (myofstream & strm, double value);
.cpp file:
void
erase_one_zero(std::
string
&
str)
{
using namespace std;
string::size_type pos= str.length() - 3;
str.erase(pos, 1);
}
myofstream & operator << (myofstream & strm, const float value)
{
using namespace std;
ostringstream oss;
oss << scientific << showpoint << setprecision(strm.get_precision()) << value;
std::string str(oss.str());
erase_one_zero(str);
strm << str;
return strm;
}
myofstream & operator << (myofstream & strm, const double value)
{
using namespace std;
ostringstream oss;
oss << scientific << showpoint << setprecision(strm.get_precision()) << value;
std::string str(oss.str());
erase_one_zero(str);
strm << str;
return strm;
}
{
using namespace std;
string::size_type pos= str.length() - 3;
str.erase(pos, 1);
}
myofstream & operator << (myofstream & strm, const float value)
{
using namespace std;
ostringstream oss;
oss << scientific << showpoint << setprecision(strm.get_precision()) << value;
std::string str(oss.str());
erase_one_zero(str);
strm << str;
return strm;
}
myofstream & operator << (myofstream & strm, const double value)
{
using namespace std;
ostringstream oss;
oss << scientific << showpoint << setprecision(strm.get_precision()) << value;
std::string str(oss.str());
erase_one_zero(str);
strm << str;
return strm;
}
test code:
int
main(
int
argc,
char
*
argv[])
{
using namespace std;
myofstream fout("out.txt");
fout << "out put scientific format: \n";
fout << 3654.002 << endl;
fout << 0.145f << endl;
fout.set_precision(6);
fout << 3654.002 << endl;
fout << 0.145f << endl;
return 0;
}
{
using namespace std;
myofstream fout("out.txt");
fout << "out put scientific format: \n";
fout << 3654.002 << endl;
fout << 0.145f << endl;
fout.set_precision(6);
fout << 3654.002 << endl;
fout << 0.145f << endl;
return 0;
}
VC6下,不知还有没有更好的办法……