前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >C++ 标准库之 iomanip 、操作符 ios::fixed 以及 setprecision 使用的惨痛教训经验总结

C++ 标准库之 iomanip 、操作符 ios::fixed 以及 setprecision 使用的惨痛教训经验总结

作者头像
Angel_Kitty
发布2019-04-22 10:31:45
2.2K0
发布2019-04-22 10:31:45
举报

本菜鸡自从退役之后就再也没怎么敲过 C++ 代码,在 C++ 语言下,求解关于浮点数类型的问题时,之前有碰到类似的情况,但是似乎都没有卡这块的数据,基本上用一个 setprecision 函数保留几位有效数字就 AC 了。但这次在计算任意五个数的平均值时卡在了一组数据上,问题如下:

代码语言:javascript
复制
#include <iostream>
#include <iomanip>
#include <stdio.h>
using namespace std;
int main(){
    float a,b,c,d,e;
    cin>>a>>b>>c>>d>>e;
    float ave = (a+b+c+d+e)*1.0/5;
    //cout<<setiosflags(ios::fixed)<<setprecision(2)<<ave*1.0<<endl;
    cout<<setprecision(2)<<ave*1.0<<endl;
    //printf("%.2f",ave);
    return 0;
}
/*
 * Problem: 连续输入5个数,数的范围为0.00~2.00,输出其平均值,并保留两位小数。
 *
**/

/*
用例:
1.82 1.86 1.88 1.65 1.78

对应输出应该为:

1.80

你的输出为:

1.8

*
**/

我们从头到尾来看看这段代码吧。

首先是头文件:#include ,我们可能没太见过,老实说我也是第一次见,以前都是用 C++ 那个总的头文件 #include<bits/stdc++.h> ,包含了全部的C++头文件,所以很多小的头文件可能都不太记得。

关于 bits/stdc++.h 的源代码如下:

代码语言:javascript
复制
// C++ includes used for precompiling -*- C++ -*-

// Copyright (C) 2003-2014 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library.  This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.

// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.

// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.

// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
// <http://www.gnu.org/licenses/>.

/** @file stdc++.h
 *  This is an implementation file for a precompiled header.
 */

// 17.4.1.2 Headers

// C
#ifndef _GLIBCXX_NO_ASSERT
#include <cassert>
#endif
#include <cctype>
#include <cerrno>
#include <cfloat>
#include <ciso646>
#include <climits>
#include <clocale>
#include <cmath>
#include <csetjmp>
#include <csignal>
#include <cstdarg>
#include <cstddef>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>

#if __cplusplus >= 201103L
#include <ccomplex>
#include <cfenv>
#include <cinttypes>
#include <cstdalign>
#include <cstdbool>
#include <cstdint>
#include <ctgmath>
#include <cwchar>
#include <cwctype>
#endif

// C++
#include <algorithm>
#include <bitset>
#include <complex>
#include <deque>
#include <exception>
#include <fstream>
#include <functional>
#include <iomanip>
#include <ios>
#include <iosfwd>
#include <iostream>
#include <istream>
#include <iterator>
#include <limits>
#include <list>
#include <locale>
#include <map>
#include <memory>
#include <new>
#include <numeric>
#include <ostream>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <stdexcept>
#include <streambuf>
#include <string>
#include <typeinfo>
#include <utility>
#include <valarray>
#include <vector>

#if __cplusplus >= 201103L
#include <array>
#include <atomic>
#include <chrono>
#include <condition_variable>
#include <forward_list>
#include <future>
#include <initializer_list>
#include <mutex>
#include <random>
#include <ratio>
#include <regex>
#include <scoped_allocator>
#include <system_error>
#include <thread>
#include <tuple>
#include <typeindex>
#include <type_traits>
#include <unordered_map>
#include <unordered_set>
#endif

include 是 I/O 流控制头文件,类似与 C 里面的格式化输出一样,记住就好,具体的一些操作符及作用可以参考下表所示。

操作符

作用

dec

设置整数为十进制

hex

设置整数为十六进制

oct

设置整数为八进制

setbase(n)

设置整数为n进制(n=8,10,16)

setfill(n)

设置字符填充,c可以是字符常或字符变量

setprecision(n)

设置浮点数的有效数字为n位

setw(n)

设置字段宽度为n位

setiosflags(ios::fixed)

设置浮点数以固定的小数位数显示

setiosflags(ios::scientific)

设置浮点数以科学计数法表示

setiosflags(ios::left)

输出左对齐

setiosflags(ios::right)

输出右对齐

setiosflags(ios::skipws)

忽略前导空格

setiosflags(ios::uppercase)

在以科学计数法输出E与十六进制输出X以大写输出,否则小写

setiosflags(ios::showpos)

输出正数时显示"+"号

setiosflags(ios::showpoint)

强制显示小数点

resetiosflags()

终止已经设置的输出格式状态,在括号中应指定内容

浮点数但是我们要记住的一点是,一个浮点数的有效数字位数默认为为 6 位,你可以通过 setprecision(n) 操作符来修改显示有效数字的有效数字的位数。但我们需要注意以下两个重要的易错点:

  • 如果有效数少于要显示的数字,则 setprecision 将舍去
  • 末尾的零将被省略

那我们如果想要根据我们自己的意愿输出小数点后相应的位数,我们又该怎么办呢?

C++ 在 iostream 头文件中定义了一个 ios::fixed 操作符,它可以使输出数据用小数点的形式打印在屏幕上。这样我们就可以人为的控制输出自己想保留小数点后相应的位数。

setiosflags(ios::fixed) 是定义在 中的函数,该操作符的作用是执行有参数指定区域内的动作,我们传入了参数 ios::fixed ,该参数指定的动作是以带小数点的形式表示浮点数,并且在允许的精度范围内尽可能的把数字移向小数点右侧。

例如我们还是拿上面那个例子来说:

代码语言:javascript
复制
cout<<ave*1.0<<endl;                                                (1)
cout<<setprecision(2)<<ave*1.0<<endl;                               (2)
cout<<setiosflags(ios::fixed)<<ave*1.0<<endl;                       (3)
cout<<setiosflags(ios::fixed)<<setprecision(2)<<ave*1.0<<endl;      (4)

根据上面所描述的那样,我们很容易得出如下结果:

代码语言:javascript
复制
(1) = 1.798
(2) = 1.8
(3) = 1.798000
(4) = 1.80
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2019-04-14 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • include 是 I/O 流控制头文件,类似与 C 里面的格式化输出一样,记住就好,具体的一些操作符及作用可以参考下表所示。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档