一千题,No.0137(舍入)

不同的编译器对浮点数的精度有不同的处理方法。常见的一种是“四舍五入”,即考察指定有效位的后一位数字,如果不小于 5,就令有效位最后一位进位,然后舍去后面的尾数;如果小于 5 就直接舍去尾数。另一种叫“截断”,即不管有效位后面是什么数字,一概直接舍去。还有一种是“四舍六入五成双”,即当有效位的后一位数字是 5 时,有 3 种情况要考虑:如果 5 后面还有其它非 0 尾数,则进位;如果没有,则当有效位最后一位是单数时进位,双数时舍去,即保持最后一位是双数。

本题就请你写程序按照要求处理给定浮点数的舍入问题。

输入格式:

输入第一行给出两个不超过 100 的正整数 N 和 D,分别是待处理数字的个数和要求保留的小数点后的有效位数。随后 N 行,每行给出一个待处理数字的信息,格式如下:

指令符 数字

其中指令符是表示舍入方法的一位数字,1 表示“四舍五入”,2 表示“截断”,3 表示“四舍六入五成双”;数字是一个总长度不超过 200 位的浮点数,且不以小数点开头或结尾,即 0.123 不会写成 .123123 也不会写成 123.。此外,输入保证没有不必要的正负号(例如 -0.0+1)。

输出格式:

对每个待处理数字,在一行中输出根据指令符处理后的结果数字。

输入样例:

7 3
1 3.1415926
2 3.1415926
3 3.1415926
3 3.14150
3 3.14250
3 3.14251
1 3.14

输出样例:

3.142
3.141
3.142
3.142
3.142
3.143
3.140

 解题思路:

写了一大坨,水多了加面,面多了加水

写了一个大数加法器,因为最大有200位小数,超范围了

然后根据题目要求输出即可

注意题目不会输入+,但是会有一个  ‘-0’  的输入,把  ‘-’  去掉即可

#include <bits/stdc++.h>

using namespace std;

int n,e;

string big_add(string a,bool &b)
{
    string res;
    int cnt = 0;
    reverse(a.begin(),a.end());
    if(a[0]-'0' + 1 > 9) cnt = 1;
    res += to_string((a[0]-'0' + 1)%10);
    for(int i = 1;i < a.size();++i)
    {
        int num = a[i]-'0' + cnt;
        if(num > 9) cnt = 1;
        else cnt = 0;
        res += to_string(num%10);
    }
    if(cnt == 1)
    {
        res += '1';
        b = !b;
    }
    reverse(res.begin(),res.end());
    return res;
}

struct num
{
    num(string d)
    :_data(d)
    {
        int t = 0;
        while(_data[t] != '.' && t < _data.size()) ++t;
        if(t != _data.size())
        {
            _left = _data.substr(0,t);
            _right = _data.substr(t+1);
            while(_right.size() < e+10) _right += '0';
        }
        else
        {
            _left = _data;
            while(_right.size() < e+10) _right += '0';
        }
    }
    void unadd()//不进位
    {
        _right = _right.substr(0,e);
    }
    void add()//进位
    {
        _right = _right.substr(0,e);
        bool b = false;
        _right = big_add(_right,b);
        if(b)
        {
            _right = _right.substr(1);
            _left = big_add(_left,b);
        }
    }
    string _data;
    string _left;
    string _right;
};

bool all_zero(string line)
{
    for(char c : line) if(c != '0') return false;
    return true;
}

int main()
{
    cin >> n >> e;
    while(n--)
    {
        bool temp = true;
        int x;
        string line;
        cin >> x >> line;
        if(line[0] == '-')
        {
            line = line.substr(1);
            temp = false;
        }
        num nu(line);
        if(x == 1)
        {
            if(nu._right[e] >= '5') nu.add();
            else nu.unadd();
            if(!temp && !(all_zero(nu._right) && all_zero(nu._left))) cout << '-';
            cout << nu._left << "." << nu._right << endl;
        }
        else if(x == 2)
        {
            nu.unadd();
            if(!temp && !(all_zero(nu._right) && all_zero(nu._left))) cout << '-';
            cout << nu._left << "." << nu._right << endl;
        }
        else
        {
            if(nu._right[e] == '5')
            {
                if(all_zero(nu._right.substr(e+1)))
                {
                    char c = nu._right[e-1];
                    if((c-'0') % 2 == 0)
                    {
                        nu.unadd();
                    }
                    else
                    {
                        nu.add();
                    }
                }
                else
                {
                    nu.add();
                }
            }
            else if(nu._right[e] <= '4')
            {
                nu.unadd();
            }
            else if(nu._right[e] >= '6')
            {
                nu.add();
            }
            if(!temp && !(all_zero(nu._right) && all_zero(nu._left))) cout << '-';
            cout << nu._left << "." << nu._right << endl;
        }
    }
    return 0;
}
  • 8
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值