不同的编译器对浮点数的精度有不同的处理方法。常见的一种是“四舍五入”,即考察指定有效位的后一位数字,如果不小于 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
分析:Z存储操作数,I表示小数点的下标,jin存储是否需要进位,now存储现在位数的数值,fu表示刚开始这个数是否有负号,fl表示输出的有效位内是否有非零数。
刚开始判断一下第一位是不是负号,是的话先存一下,因为如果最后全部是0的情况,不用输出负号(如D = 3, s = -0.0000001时0.000)。
记录一下小数点的位置,如果是个整数就没有小数点,可以自己手动补充一个,因为D是正整数。同时,我们可以在原来的数后面加几个零,方便后续的运算。
如果操作数是1,可以在有效位后1位上加5表示进位,如果操作数是2则不用操作,如果操作为是3,按照题目要求进行模拟。
最后按照大数加法(高精加)的计算方式将数字更新一下,如果前面还有进位就加一个1在左边。在fu和fl都位1的情况下,提早输出一个负号。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 |
#include <iostream> using namespace std; int N, D, Z, I, jin, now, fu, fl; string s, zero(200, '0'); int main() { cin >> N >> D; while (N--) { I = jin = fu = fl = 0; cin >> Z >> s; if (s[0] == '-') { fu = 1; s.erase(0, 1); } while (I < s.size() && s[I] != '.') ++I; if (I == s.size()) s = s + '.'; s = s + zero; if (Z != 2) { if (Z == 1) s[I + D + 1] += 5; else { if (s[I + D + 1] >= '6') s[I + D]++; else if (s[I + D + 1] == '5') { int flag = 0; for (int i = I + D + 2; i < s.size(); i++) { if(s[i] != '0') { s[I + D]++; flag = 1; break; } } if (flag == 0 && s[I + D] & 1) ++s[I + D]; } } for (int i = I + D + 1; i >= 0; i--) { if (s[i] == '.') continue; now = s[i] - '0' + jin; s[i] = '0' + now % 10; jin = now / 10; } } if (jin) s = '1' + s, I++; if (fu) { for (int i = 0; i <= I + D; i++) { if (s[i] != '0' && s[i] != '.') fl = 1; } } if (fu && fl) cout << '-'; cout << s.substr(0, I + D + 1) << "\n"; } return 0; } |
❤ 点击这里 -> 订阅《PAT | 蓝桥 | LeetCode学习路径 & 刷题经验》by 柳婼