TB椰程 TypeBuddy 打字搭子

【例14.2】 四舍六入五留双

C++语法 · 顺序结构 · 代码 · cpp · 难度 5/5 · 共 1454 字

按银行家舍入法保留 d 位小数

  • C++语法
  • 例题

正文

// 原题:https://oj.yecheng.tv/p/P74
// 题意:保留 d 位小数,恰为 0.5 时向偶数舍入
//       (如 0.5→0、1.5→2、2.5→2),否则四舍六入。
//       f 最多 30 位小数,必须用字符串处理。
// 思路:截取第 d+1 位起的尾数:
//       大于 0.5 进位、小于 0.5 舍去、
//       恰好 0.5 看保留末位奇偶,最后处理进位。
#include <iostream>
using namespace std;

int main() {
    string s;
    int d;
    cin >> s >> d;
    // 拆出整数部分和小数部分
    string intPart = "0", frac;
    int dot = s.find('.');
    if (dot == -1) intPart = s;
    else {
        intPart = s.substr(0, dot);
        frac = s.substr(dot + 1);
    }
    // 补齐到 d+1 位,便于统一比较
    while ((int)frac.size() < d + 1) frac += '0';
    string rest = frac.substr(d);
    // rest 与 0.5 比较:首位大于 5 或等于 5 后还有非零 → 超过一半
    bool overHalf = rest[0] > '5';
    bool halfExactly = rest[0] == '5';
    if (halfExactly) {
        for (int i = 1; i < (int)rest.size(); i++) {
            if (rest[i] != '0') { halfExactly = false; overHalf = true; break; }
        }
    }
    bool up = overHalf || (halfExactly && (frac[d - 1] - '0') % 2 == 1);
    if (up) {
        // 从第 d 位往前进位
        int i = d - 1;
        while (i >= 0 && frac[i] == '9') frac[i--] = '0';
        if (i >= 0) frac[i]++;
        else {
            // 整数部分进位
            int j = (int)intPart.size() - 1;
            while (j >= 0 && intPart[j] == '9') intPart[j--] = '0';
            if (j >= 0) intPart[j]++;
            else intPart = "1" + intPart;
        }
    }
    cout << intPart << "." << frac.substr(0, d) << endl;
    return 0;
}

C++语法 · 顺序结构的其它内容

打字首页 · 词库画廊 · 编程打字 · 指法入门 · 天梯榜 · 数据分析 · 班级课堂 · 关于我们
椰程 TypeBuddy 打字搭子 —— 键盘指法练习 · 单词记忆 · 班级课堂 · 在线 PK