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

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

    #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 的源代码如下:

    // 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 ,该参数指定的动作是以带小数点的形式表示浮点数,并且在允许的精度范围内尽可能的把数字移向小数点右侧。

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

    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)
    

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

    (1) = 1.798
    (2) = 1.8
    (3) = 1.798000
    (4) = 1.80
    
  • 相关阅读:
    十进制数转换
    桶排序
    快速排序
    单词倒排
    (c++) string b; cin>>b; int i=strlen(b); 报错的原因。
    n的阶乘(1<n<10000)(结果超大……)
    2020软件工程最后一次作业
    2020软件工程第四次作业
    2020软件工程第三次作业
    2020软件工程第二次作业
  • 原文地址:https://www.cnblogs.com/ECJTUACM-873284962/p/10705252.html
Copyright © 2011-2022 走看看