不同的编译器对浮点数的精度有不同的处理方法。常见的一种是“四舍五入”,即考察指定有效位的后一位数字,如果不小于 5,就令有效位最后一位进位,然后舍去后面的尾数;如果小于 5 就直接舍去尾数。另一种叫“截断”,即不管有效位后面是什么数字,一概直接舍去。还有一种是“四舍六入五成双”,即当有效位的后一位数字是 5 时,有 3 种情况要考虑:如果 5 后面还有其它非 0 尾数,则进位;如果没有,则当有效位最后一位是单数时进位,双数时舍去,即保持最后一位是双数。
本题就请你写程序按照要求处理给定浮点数的舍入问题。
输入格式:
输入第一行给出两个不超过 100 的正整数 N 和 D,分别是待处理数字的个数和要求保留的小数点后的有效位数。随后 N 行,每行给出一个待处理数字的信息,格式如下:
指令符 数字
其中指令符
是表示舍入方法的一位数字,1
表示“四舍五入”,2
表示“截断”,3
表示“四舍六入五成双”;数字
是一个总长度不超过 200 位的浮点数,且不以小数点开头或结尾,即 0.123
不会写成 .123
,123
也不会写成 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;
}