C++中为何内置函数及自定义代码无法将0.5小数四舍五入为1?
C++ 自定义取整逻辑错误:0.5未按预期舍入为1的修复方案
问题说明
需求是实现特定小数取整规则:小数部分小于0.4时舍入为0,0.5及以上时舍入为1(本质是标准四舍五入,0.5向上取整)。但当前自定义代码处理时,无论正负数值,0.5的情况都被错误舍入为0,导致实际输出与期望结果不符。
原代码
#include <iostream> #include <vector> #include <cmath> int main(){ using namespace std; int a, b, n; cin >> n; int arr[n]; double prod; for(int i = 0; i < n; i++){ cin >> a >> b; prod = a/b; if(prod < 0){ arr[i] = (int)(prod-0.5); } else { arr[i] = (int)(prod+0.5); } } for(int i = 0; i < n; i++){ cout << arr[i] << " "; } }
测试数据
13 --> Size of the array. 571518625 -24104 -1893729058 -436796 2104753595 -158270 -822607240 72830 0 -79061 -627632490 -31441 369212137 18046 976324350 -57100 487246561 24578 -1317758661 119682 0 5341 1098940248 -68272 -923153725 61895
实际输出
-23710 4335 -13298 -11294 0 19962 20459 -17098 19824 -11010 0 -16096 -14914
期望输出
-23711 4336 -13299 -11295 0 19962 20460 -17099 19825 -11011 0 -16097 -14915
问题根源
- 整数除法丢失精度:原代码中
a和b均为int类型,a/b执行的是整数除法,直接丢弃小数部分,得到的整数结果再赋值给double类型的prod,此时prod已无真实小数部分,后续的+0.5或-0.5操作无法反映除法的实际结果。 - 强制类型转换的截断规则:C++中
(int)对浮点数的转换是向零截断,而非四舍五入。例如20459.5转int会得到20459,-23710.5转int会得到-23710,完全不符合需求的四舍五入逻辑。
修复方案
关键修改点
- 改为浮点数除法:将
prod = a/b;改为prod = static_cast<double>(a)/b;,先把其中一个操作数转为double,触发浮点数除法以保留小数部分。 - 使用标准库
round()函数:round()会将浮点数四舍五入到最近整数,且0.5会向上取整(包括负数场景,如round(-23710.5)得到-23711),完全匹配需求。 - 替换非标准变长数组:原代码
int arr[n];是C99特性,C++标准不支持,改用vector<int>保证代码可移植性。
修改后的代码
#include <iostream> #include <vector> #include <cmath> int main(){ using namespace std; int a, b, n; cin >> n; vector<int> arr(n); double prod; for(int i = 0; i < n; i++){ cin >> a >> b; // 转为浮点数后执行除法,保留小数部分 prod = static_cast<double>(a) / b; // 用round函数完成四舍五入 arr[i] = static_cast<int>(round(prod)); } for(int val : arr){ cout << val << " "; } return 0; }
验证结果
运行修改后的代码,输入测试数据,将得到与期望完全一致的输出。
内容的提问来源于stack exchange,提问作者Kevin Jonathan
相关产品推荐
相关产品推荐

