C++程序中%运算符的问题
给定n和m以及p,保证n>=m,求(n!-m!)对p取余的结果。默认数据满足:n,m<=20,p<=10000我写了两个程序,第一个是错的,第二个是对的(参考同学之后)。...
给定n和m以及p,保证n>=m,求(n!-m!)对p取余的结果。默认数据满足:n,m<=20,p<=10000
我写了两个程序,第一个是错的,第二个是对的(参考同学之后)。问一下第一个错在哪里?第二个注释行中+p有什么作用?
//程序一
#include <iostream>
using namespace std;
int Factorial (unsigned int a);
int main(){
unsigned int n, m, p, result;
cin >> n >> m >> p;
if (n >= m)
{
result = (Factorial (n) - Factorial (m) + p) % p;
cout << result;
return 0;
}
else
return 1;
}
int Factorial (unsigned int a){
int f = 1;
while (a >= 1)
f = f * a --;
return f;
}
//程序二
#include <iostream>
using namespace std;
int ModPFactorial (unsigned int a, unsigned int p);
int main(){
unsigned int n, m, p, result;
cin >> n >> m >> p;
result = (ModPFactorial (n, p) - ModPFactorial (m, p) + p) % p; //括号里的+p作用?
cout << result;
return 0;
}
int ModPFactorial (unsigned int a, unsigned int p)
{
int f = 1;
while (a >= 1)
f = (f * a--) % p;
return f;
} 展开
我写了两个程序,第一个是错的,第二个是对的(参考同学之后)。问一下第一个错在哪里?第二个注释行中+p有什么作用?
//程序一
#include <iostream>
using namespace std;
int Factorial (unsigned int a);
int main(){
unsigned int n, m, p, result;
cin >> n >> m >> p;
if (n >= m)
{
result = (Factorial (n) - Factorial (m) + p) % p;
cout << result;
return 0;
}
else
return 1;
}
int Factorial (unsigned int a){
int f = 1;
while (a >= 1)
f = f * a --;
return f;
}
//程序二
#include <iostream>
using namespace std;
int ModPFactorial (unsigned int a, unsigned int p);
int main(){
unsigned int n, m, p, result;
cin >> n >> m >> p;
result = (ModPFactorial (n, p) - ModPFactorial (m, p) + p) % p; //括号里的+p作用?
cout << result;
return 0;
}
int ModPFactorial (unsigned int a, unsigned int p)
{
int f = 1;
while (a >= 1)
f = (f * a--) % p;
return f;
} 展开
2个回答
展开全部
错在哪里?
阶乘运算会数值溢出。
通常 int 是32bit,而 20! = 2432902008176640000 > 2^32 = 4294967296 。
而 2^64 = 18446744073709551616 > 20! ,所以若你使用 64bit 的整型类型变量来做乘法运算也许能够得到正确结果。
+p作用?
函数ModPFactorial的返回值总是在[0,p)范围内。所以虽然 n>=m,但是减法仍然可能小于 0 ,为了正确取余,加个 p 以避免是负值。
阶乘运算会数值溢出。
通常 int 是32bit,而 20! = 2432902008176640000 > 2^32 = 4294967296 。
而 2^64 = 18446744073709551616 > 20! ,所以若你使用 64bit 的整型类型变量来做乘法运算也许能够得到正确结果。
+p作用?
函数ModPFactorial的返回值总是在[0,p)范围内。所以虽然 n>=m,但是减法仍然可能小于 0 ,为了正确取余,加个 p 以避免是负值。
展开全部
你的程序没有什么问题,我试了几个数,也仔细看了代码,完全符合你条件控制的要求。
你同学的程序的大意是,先求出给定两个数各自阶乘后直接求余的结果,然后作差加一个被除数再求余。作差后又加一个p的原因是,如果做出的差是负数,由于ModPFactorial函数返回int,而调用它时后面有一个对unsigned int的求余运算,此时如果不加p,就会是一个负的int值对unsigned int求余,而c++会将int自动转换为unsigned int。虽然int 和 unsigned都是用补码存储,但是int有最高符号位(负数为1),而unsigned是将32位全部算为数据位,因此转换后所得的余数差值是一个完全不同的数(其实是溢出,但运行不会报错)。如果加p,得到的值一定为正,因为两个除p余数的差值一定小于p,此时差值符号位为0,与unsigned一样,因此转换正确也能得到正确结果。
不过建议尽量还是将类型统一一下,因为简单的问题让它自动转一下还好,如果做大程序甚至项目的时候这么弄很容易出问题。
你的程序不知道你说的有错在哪,你可以说几个错误的例子。还有,你写的那个求result时是不用加p的。
你同学的程序的大意是,先求出给定两个数各自阶乘后直接求余的结果,然后作差加一个被除数再求余。作差后又加一个p的原因是,如果做出的差是负数,由于ModPFactorial函数返回int,而调用它时后面有一个对unsigned int的求余运算,此时如果不加p,就会是一个负的int值对unsigned int求余,而c++会将int自动转换为unsigned int。虽然int 和 unsigned都是用补码存储,但是int有最高符号位(负数为1),而unsigned是将32位全部算为数据位,因此转换后所得的余数差值是一个完全不同的数(其实是溢出,但运行不会报错)。如果加p,得到的值一定为正,因为两个除p余数的差值一定小于p,此时差值符号位为0,与unsigned一样,因此转换正确也能得到正确结果。
不过建议尽量还是将类型统一一下,因为简单的问题让它自动转一下还好,如果做大程序甚至项目的时候这么弄很容易出问题。
你的程序不知道你说的有错在哪,你可以说几个错误的例子。还有,你写的那个求result时是不用加p的。
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
推荐律师服务:
若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询