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)//是否有小数点呢?
{
//检查小数的位数
}

时间: 2024-10-12 04:32:47

C++中对浮点数的格式化显示的相关文章

在ASP中按指定参数格式化显示时间的函数。

函数|显示|函数 <%'该函数作用:按指定参数格式化显示时间.'numformat=1:将时间转化为yyyy-mm-dd hh:nn格式.'numformat=2:将时间转化为yyyy-mm-dd格式.'numformat=3:将时间转化为hh:nn格式.'numformat=4:将时间转化为yyyy年mm月dd日 hh时nn分格式.'numformat=5:将时间转化为yyyy年mm月dd日格式.'numformat=6:将时间转化为hh时nn分格式.'numformat=7:将时间转化为yy

在ASP中按指定参数格式化显示时间的函数

函数|显示|函数 <%'该函数作用:按指定参数格式化显示时间.'numformat=1:将时间转化为yyyy-mm-dd hh:nn格式.'numformat=2:将时间转化为yyyy-mm-dd格式.'numformat=3:将时间转化为hh:nn格式.'numformat=4:将时间转化为yyyy年mm月dd日 hh时nn分格式.'numformat=5:将时间转化为yyyy年mm月dd日格式.'numformat=6:将时间转化为hh时nn分格式.'numformat=7:将时间转化为yy

浅析C语言字中的符串格式化显示_C 语言

符号                  作用 ──────────────────────────     %d              十进制有符号整数     %i              输入整数 ,可以是带前导0的八进制数或0x的十六进制数    %u              十进制无符号整数     %f              浮点数     %s              字符串     %c              单个字符     %p              指针

解析C++ 浮点数的格式化显示_C 语言

代码如下所示: 复制代码 代码如下:     #include <stdlib.h>      #include <string>      #include <windows.h>      #include <stdio.h>      #include <iostream>      #include <limits>      #include <sstream>      using namespace std;

PHP中常见的格式化显示时间日期函数

time()函数 time() 函数返回当前时间的 Unix 时间戳.返回自从 Unix 纪元(格林威治时间 1970 年 1 月 1 日 00:00:00)到当前时间的秒数. 自 PHP 5.1 起在 $_SERVER['REQUEST_TIME'] 中保存了发起该请求时刻的时间戳.  代码如下 复制代码 <?php $time = time(); echo($time . "<br />"); echo(date("D F d Y", $tim

报表中每隔N行显示一条粗线

问题: 如何在报表中每隔N行显示一条粗线 如何为报表增加一个行号列? 回答: 1.在设计模式里打开该报表,在报表主体里面加一个TextBox,把Name属性改为InputID. 2.把InputID的控件来源(ControlSource)属性设置为=1:再把InputID的运行总和(RunningSum)属性改为"全部之上"(OverAll). 注意:如果把这个控件显示给用户看,你将得到一个以1为步进自动增长的行号列 3.最后,在主体的格式化事件里输入如下代码: 以下为引用的内容:Pr

如何在Access报表中每隔N行显示一条粗线

access|显示 如何在Access报表中每隔N行显示一条粗线   问题: 如何在报表中每隔N行显示一条粗线如何为报表增加一个行号列?  回答:     1.在设计模式里打开该报表,在报表主体里面加一个TextBox,把Name属性改为InputID.    2.把InputID的控件来源(ControlSource)属性设置为=1:再把InputID的运行总和(RunningSum)属性改为"全部之上"(Over All).    注意:如果把这个控件显示给用户看,你将得到一个以1

微型项目实践(11):控件与格式化显示

上一篇文章中,我们简单的分析了页面的设计,今天我们来看页面中的动态部分.Master和Default页 面中的主要控件如下表: 控件ID 描述 Calendar Asp.Net自带的日历控件,使用自带的样式,以后我们会使用该控件实现根据日期的查询. ListView_BlogClass ListView,用于显示日志分类.该控件生成的Html全部是连接,不需要响应事件,故 EnableViewState设置为false. ListView_BlogList ListView,用于显示日志.该控件

python中日期和时间格式化输出的方法小结

 这篇文章主要介绍了python中日期和时间格式化输出的方法,实例总结了Python常见的日期与事件操作技巧,非常具有实用价值,需要的朋友可以参考下     本文实例总结了python中日期和时间格式化输出的方法.分享给大家供大家参考.具体分析如下: python格式化日期时间的函数为datetime.datetime.strftime():由字符串转为日期型的函数为:datetime.datetime.strptime(),两个函数都涉及日期时间的格式化字符串,这里提供详细的代码详细演示了每一