C++四舍五入超大十进制数时出现异常输出问题求解
问题成因
int64_t是有符号64位整数类型,可表示范围为-9223372036854775808~9223372036854775807,你输入的样例数值整数部分远大于该范围上限,C++标准明确规定,超出目标整数类型表示范围的浮点数强制转换行为是未定义的,本次运行触发了整数溢出、符号位翻转,所以输出了异常负数。- 即使不做强制类型转换,
long double的十进制有效位数通常仅为18~19位,你输入的超长数值远超出该精度范围,从输入字符串转成long double的阶段就已经丢失了低位精度,根本无法准确还原整数和小数部分的真实值,本身就不可能得到正确的四舍五入结果。
修复方案
处理超长十进制数的四舍五入不要转成数值类型,直接以字符串形式解析输入即可,逻辑如下:
- 读取输入为字符串,查找小数点位置
- 无小数点直接输出原字符串
- 有小数点则取小数点后第一位判断是否大于等于'5',小于则直接输出整数部分
- 若满足进位条件,对整数部分字符串做加1进位处理后输出
修复后代码:
#include <iostream> #include <string> using namespace std; // 整数部分字符串加1进位工具函数 string addOne(string num) { int carry = 1; for (int i = num.size() - 1; i >= 0 && carry; --i) { int digit = num[i] - '0' + carry; if (digit == 10) { num[i] = '0'; carry = 1; } else { num[i] = digit + '0'; carry = 0; } } if (carry) num.insert(num.begin(), '1'); return num; } int main(){ string s; cin >> s; size_t dotPos = s.find('.'); if (dotPos == string::npos) { cout << s; return 0; } string intPart = s.substr(0, dotPos); if (dotPos + 1 < s.size() && s[dotPos + 1] >= '5') { intPart = addOne(intPart); } cout << intPart; return 0; }
内容的提问来源于stack exchange,提问作者Aquib
相关产品推荐
相关产品推荐

