#include <iostream>
using namespace std;
int getFectorial(int n)
{
int ans = 1;
for (int i = n; i >= 1; i--)
{
ans = ans * i;
}
return ans;
}
int printNcr(int n, int r)
{
if (getFectorial(n) > INT_MAX)
{
return 0;
}
return (getFectorial(n)) / ((getFectorial(r)) * (getFectorial(n - r)));
}
int main()
{
int n = 14;
for (int row = 0; row < n; row++)
{
for (int col = 0; col < row + 1; col++)
{
cout << printNcr(row, col) << " ";
}
cout << endl;
}
return 0;
}
当我给n
的值超过13时,我想要整数溢出条件应该在printNcr()
函数中给定的工作,但它不工作,13之后的所有行都打印错误的值,而不是返回false
。
如何使给定的INT_MAX
条件工作?
int
溢出发生后无法可靠检测
在factorial中检测即将到来的int
溢出的一种方法:
int getFactorial(int n) {
if (n <= 0) {
return 1; // and maybe other code when n < 0
}
int limit = INT_MAX/n;
int ans = 1;
for (int i = 2; i <= n; i++) {
if (ans >= limit) {
return INT_MAX; // Or some other code
}
ans = ans * i;
}
return ans;
}
另一种方法是在启动时,执行一次最大n
的计算。对于普通的32位int
,该限制为12。
int getFactorial(int n) {
if (n > getFactorial_pre_calculated_limit) {
return INT_MAX;
}
...
可以通过观察负值来检测溢出
int getFectorial(int n)
{
int ans = 1;
for (int i = n; i >= 1; i--)
{
ans = ans * i;
if (ans < 0) <<<<======
return -1;
}
return ans;
}
然后
int printNcr(int n, int r)
{
if (getFectorial(n) < 0)
{
return 0;
}
return (getFectorial(n)) / ((getFectorial(r)) * (getFectorial(n - r)));
}
请注意,严格来说,这是未定义的行为。如果你知道结果会太大,那就干脆失败吧。13)
或者最好这样做
int getFectorial(int n)
{
long long ans = 1; <<<====
for (int i = n; i >= 1; i--)
{
ans = ans * i;
if (ans >INT_MAX) <<<<======
return -1;
}
return (int)ans;
}
或者抛出std::overflow_error
顺便说一句,这个词是阶乘的,不是阶乘的