C++中remainder函数为何在部分场景返回错误余数?
解决C++ remainder()函数返回负数余数的问题
问题出在你对remainder()函数的逻辑理解偏差上,它和日常认知的“取余”规则不同:
remainder(x, y)的计算逻辑是返回x - n*y,其中n是最接近x/y的整数(若x/y恰好处于两个整数中间,n取偶数)。- 我们需要的“配秒余数”是总秒数减去分钟数对应的整数秒数,本质是
x - y*floor(x/y)(商向下取整,结果非负),这是fmod()函数的行为。
你的案例具体分析:
输入15.1mph时,pace = 3600 / 15.1 ≈ 238.4106秒:
pace / 60 ≈ 3.9735,通过int pace_mins截断得到3(自动向下取整)。- 但
remainder(238.4106, 60)计算时,最接近3.9735的整数是4,因此余数为238.4106 - 60*4 = -1.5894,这就是负数的来源。
三种可行解决方法:
1. 改用fmod()函数(推荐)
fmod()会返回符合预期的非负余数,直接替换代码中的remainder即可:
pace_secs = fmod(pace, 60);
2. 手动计算余数
既然已经通过int截断得到分钟数,直接用总秒数减去分钟对应的整数秒数,逻辑更直观:
pace_secs = pace - pace_mins * 60;
3. 修正remainder()的结果
如果一定要保留remainder(),可以对负数结果做补正:
pace_secs = remainder(pace, 60); if (pace_secs < 0) { pace_secs += 60; }
修改后的完整代码示例(以手动计算为例):
#include <iostream> #include <conio.h> #include <cmath> using namespace std; int main(int argc, char *argv[]) { char ans1, ans2; double mph, pace, pace_secs; int pace_mins; do { do { cout << "Please input a speed (in miles per hour) to be converted to a standard pace\n"; cin >> mph; cout << "You have entered " << mph << " miles per hour, is this correct?\n"; cin >> ans1; } while (ans1 != 'y' && ans1 != 'Y'); pace = (3600 / mph); pace_mins = static_cast<int>(pace / 60); // 显式类型转换更清晰 pace_secs = pace - pace_mins * 60; // 手动计算非负余数 cout << "If you are running at " << mph << " miles per hour it will take you "; if (pace_mins == 1) cout << pace_mins << " minute and "; else cout << pace_mins << " minutes and "; cout << pace_secs << " seconds to run one mile\n"; cout << "Would you like to run the program again?\n"; cin >> ans2; } while (ans2 != 'n' && ans2 != 'N'); return 0; }
内容的提问来源于stack exchange,提问作者Shinigami Kidd Death the Kid
相关产品推荐
相关产品推荐

