当前位置:七道奇文章资讯编程技术VC/C++编程
日期:2011-03-22 13:55:00  来源:本站整理

<b>C++中对浮点数的格局化显示</b>[VC/C++编程]

赞助商链接



  本文“<b>C++中对浮点数的格局化显示</b>[VC/C++编程]”是由七道奇为您精心收集,来源于网络转载,文章版权归文章作者所有,本站不对其观点以及内容做任何评价,请读者自行判断,以下是其具体内容:

在很多利用程序范畴中,都需求掌握小数点后的小数位,但是浮点数对此不能供应直接的支持.怎样对程序中的浮点数据举行"整齐"地格局化呢?在此我们有一个迂回的办法,先把它们转换为字符串,格局化后以文本情势显示出来.

在平常编程中--包含对话框、关系数据库、金融程序、SMS程序及一切处理数据文件的程序,需求掌握小数点后的小数位的情形非常广泛,本文中将要讲授若何用简单的办法来掌握小数位,别的,还要揭开字符串及数据精度的一点点小奥秘.

问题的引出

若有一个函数,其可承受一个long double参数,并将参数转换为字符串,后果字符串应保存两位小数,比方,浮点值123.45678应当生成"123.45"这样的字符串.表面上看来这是一个意义不大的编程问题,但是,假如真要在实际中派上用场,函数应计划为具有一定弹性,以答应调用者指定小数位数.别的,函数也应当可以处理各种非常情形,如像123.0或123这样的整数.

在开始之前,先看一下编写"文雅"C++代码时的两句"真言":

"真言"1:无论什么时刻需求格局化一个数值,都应先转换为一个字符串.这样可保证每位数刚好占据一个字符.

"真言"2:在需求转换为字符串时,请利用<sstream>库.

转换函数的接口非常简便:第一个参数是需被格局化的数值;第二个参数代表小数点后显示的小数位,且应当具有一个默许值;返回值为一个string范例:

string do_fraction(long double value, int decplaces=3);
  注意,第二个参数代表的小数位数中包含了小数点,因此,两位小数需求默许值为3.

精度问题

当然,第一步是把long double值转换为一个string,利用尺度C++库<sstream>简直是手到擒来.但是,有一件事情必须惹起注意,因为某些缘由,stringstream对象默许精度为6,而很多程序员错误地把"精度"理解为小数的位数,这是不精确的,精度应指代全部位数.因而,数字1234.56可安全地通过默许精度6来表示,但12345.67会被截断为12345.6.这样的话,假如你有一个非常大的数,如1234567.8,它的后果会静暗暗地转换为科学记数法:1.23457e+06,这明显不是我们想要的.为避免这样的麻烦,在开始转换之前,应把默许精度设为最大.
  为得到long double能表示的最大位数,可以利用<limits>库:

string do_fraction(long double value, int decplaces=3)
{
int prec=numeric_limits<long double>::digits10; // 18
ostringstream out;
out.precision(prec);//覆盖默许精度
out<<value;
string str= out.str(); //从流中取出字符串 数值目前存储在str中,等候格局化.
  小数点的位置

要举行格局化,首先要肯定小数点的位置,假如小数位多于decplaces,do_fraction()会删除多余的.

要定位小数位,可以利用string::find(),在STL算法中利用了一个常量来代表"数值未找到",在字符串中,这个常量为string::npos:

char DECIMAL_POINT='.'; // 欧洲用法为','
size_t n=str.find(DECIMAL_POINT);
if ((n!=string::npos)//能否有小数点呢?
{
//查抄小数的位数
}
  假如没有小数点,函数直接返回字符串,不然,函数将持续查抄小数位能否多于decplaces.假如是,小数部份将会被截断:

size_t n=str.find(DECIMAL_POINT);
if ((n!=string::npos)//有小数点吗?
&&(str.size()> n+decplaces)) //背面至少还有decplaces位吗?
//在小数decplaces位之后写入nul
str[n+decplaces]='';
  最后一行覆盖了多余的小数位,它利用了常量来截断字符串,要注意,string对象的数据可以包含nul字符;而字符串的实际长度由size()的返回值决意.因此,你不能假定字符串已被精确地格局化,换句话来说,假如在str中本来为"123.4567",在插入常量之后,它变成了"123.457",为把str缩减为"123.45",普通可以利用自交换的办法: str.swap(string(str.c_str()) );//删除nul之后的多余字符
  那它的原理是什么呢?函数string::c_str()返回一个const char *代表此字符串对象,而这个值被用作一个暂时string对象的初始化值,接着,暂时对象又被用作str.swap()的参数,swap()会把值"123.45"赋给str.一些老一点的编译器不支持默许模板参数,大概不会让swap()通过编译,假如是这样的话,利用手工交换来替换:

string temp=str.c_str();
str=temp;
  代码虽不是很"美好",但能到达目的就行.以下是do_fraction()的完好代码:

string do_fraction(long double value, int decplaces=3)
{
 ostringstream out;
 int prec=
 numeric_limits<long double>::digits10; // 18
 out.precision(prec);//覆盖默许精度
 out<<value;
 string str= out.str(); //从流中取出字符串
 size_t n=str.find(DECIMAL_POINT);
 if ((n!=string::npos) //有小数点吗?
 && (str.size()> n+decplaces)) //背面至少还有decplaces位吗?
 {
  str[n+decplaces]='';//覆盖第一个多余的数
 }
 str.swap(string(str.c_str()));//删除nul之后的多余字符
 return str;
}
  假如不想通过传值返回一个string对象,还可增添一个参数,把str对象以引用传送:

void do_fraction(long double value, string & str, int decplaces=3);
  从个人的角度来说,还是偏向于让编译器做这样的优化,别的,利用传值返回,还可以让你以下面这种方法利用do_fraction():

cout << funct(123456789.69999001) << '  ' << funct(12.011)<<endl;
  输出:


  123456789.69 12.01


  以上是“<b>C++中对浮点数的格局化显示</b>[VC/C++编程]”的内容,如果你对以上该文章内容感兴趣,你可以看看七道奇为您推荐以下文章:
  • <b>hosts是什么 hosts文件在什么位置 若何改正hosts</b>
  • <b>在 Windows 8 中手动安装语言包</b>
  • <b>五个常见 PHP数据库问题</b>
  • Windows中Alt键的12个高效快速的利用本领介绍
  • <b>MySQL ORDER BY 的实现解析</b>
  • <b>详解MySQL存储历程参数有三种范例(in、out、inout)</b>
  • <b>Win8系统恢复出来经典的开始菜单的办法</b>
  • <b>Win8系统花屏怎么办 Win8系统花屏的办理办法</b>
  • <b>Windows 7系统下无线网卡安装</b>
  • <b>为什么 Linux不需求碎片整理</b>
  • <b>Windows 8中删除账户的几种办法(图)</b>
  • <b>教你如安在win7下配置路由器</b>
  • 本文地址: 与您的QQ/BBS好友分享!
    • 好的评价 如果您觉得此文章好,就请您
        0%(0)
    • 差的评价 如果您觉得此文章差,就请您
        0%(0)

    文章评论评论内容只代表网友观点,与本站立场无关!

       评论摘要(共 0 条,得分 0 分,平均 0 分) 查看完整评论
    Copyright © 2020-2022 www.xiamiku.com. All Rights Reserved .