刚刚做了一个杭电的题目,上面有个要求是输出时要求保留小数点后几位数字后然后输出。既然又看到了这个熟悉的字眼和要求,那就在这里稍微写些东西算是记载一下吧,也算是一个小总结,不过这里总结的只是目前我所想到的,后续还有待补充。】
1. C++中格式控制
在C++中,说到保留小数点后几位有效数字,就会想起setprecision,马上去cplusplus上查了下有关setprecision的资料,看了后明白了,懒得逐字翻译,直接贴在下面了:
Set decimal precision
Sets the decimal precision to be used by output operations.
Behaves as if a call to the stream's member ios_base::precision with n as argument was made.
The decimal precision determines the maximum number of digits to be written on insertion operations to express floating-point values. How this is interpreted depends on whether the floatfield format flag is set to a specific notation (either fixed or scientific) or it is unset (using the default notation, which is neither fixed nor scientific):
- On the default floating-point notation, the precision field specifies the maximum number of meaningful digits to display in total counting both those before and those after the decimal point. Notice that it is not a minimum and therefore it does not pad the displayed number with trailing zeros if the number can be displayed with less digits than the precision. (此处稍微解释下:在默认情况下,setprecision(n)中的参数n表示的是小数点前后所有的有效数字(从第一个不是0的数字开始计数)位数,并且如果数字本身所有的小数位数比要求保留的位数少的话,不再后面加零凑齐所要求的位数,而在下面所说的fixed和scientific情况下setprecision(n)中的参数n表示的才是小数点后的有效数字位数,并且如果数字本身所有的小数位数比要求保留的位数少的话,在后面加零凑齐,这几点在应用中要注意。)
- In both the fixed and scientific notations, the precision field specifies exactly how many digits to display after the decimal point, even if this includes trailing decimal zeros. The number of digits before the decimal point does not matter in this case.
This manipulator is declared in header <iomanip>, along with the other parameterized manipulators: resetiosflags, setiosflags, setbase, setfill and setw. This header file declares the implementation-specific smanip type, plus any additional operator overload function needed to allow these manipulators to be inserted and extracted to/from streams with their parameters.
测试代码如下:
#include
<
iostream
>
#include
<
iomanip
>
using
namespace
std;
int
main()
{
//以下所有保留小数的情形都考虑了四舍五入的情况
double t = 1.125;
//以下语句中的2包括小数点前的数字1
cout<<setprecision(2)<<t<<endl;
//虽然5>3,但是输出结构不用0来凑齐
cout<<setprecision(5)<<t<<endl;
//注意:一旦在下一条语句中加入了格式控制fixed,那么在后面的cout语句中
//除非显示的改变格式控制,否则就默认按照前面规定的fixed格式输出
cout<<fixed<<setprecision(2)<<t<<endl;
//以下两条语句的输出格式是一样的
cout<<setprecision(5)<<t<<endl;
cout<<fixed<<setprecision(5)<<t<<endl;
//显示修改了输出控制方式,以下两条语句的输出格式也是一样的
cout<<scientific<<setprecision(2)<<t<<endl;
cout<<setprecision(2)<<t<<endl;
return 0;
}
输出如下:
注意:以上是默认四舍五入的.
2. 直接用C语言输出语句printf就可以搞定
测试代码如下:
#include
<
cstdio
>
using
namespace
std;
int
main()
{
double t = 1.23456;
printf("%0.3f\n",t);
printf("%0.4f\n",t);
printf("%0.5f\n",t);
printf("%0.6f\n",t);
return 0;
}
输出结果为:
从第二个输出我们也可以看出,printf的格式控制默认也是四舍五入的。
3. 自己想办法模拟实现。
写了个代码如下:
#include
<
iostream
>
using
namespace
std;
double
n_hundred(
int
n)
{
double sum = 1.0;
for(int i = 1;i <= n;++i)
sum = sum *10;
return sum;
}
double
process(
double
t,
int
n)
{
//如果要求保留t小数点后n位数字的话
int ival = (int)(t * n_hundred(n));
//看小数点后第n+1位数字是否大于5来进行四舍五入
int temp = (int)(t * n_hundred(n+1))%10;
if(temp >= 5)
ival = ival + 1;
double dval = ival/n_hundred(n);
return dval;
}
int
main()
{
double t = 1.23456;
cout<<process(t,3)<<endl;
cout<<process(t,4)<<endl;
cout<<process(t,8)<<endl;
return 0;
}
输出结果如下:
处理基本的四舍五入和保留小数点后几位有效数字是可以的,但是有一个问题,就是如果要求保留的小数位数比现有的小数位数多的话,后面没法用0来补齐,就像上面程序的第三个输出那样的。
好了,先写到这里了,以后有新想法了再来继续写。