C++中的乘法溢出
在我的代码中,我尝试将两个数字相乘。算法很简单,如k*k-1^n。我将乘积k-1^n存储在变量p1中,然后将其与k相乘。对于n=10,k=10 k-1^n-1应该是387420489,我在变量p1中得到了这个值,但将其与k相乘后,我得到了一个负数。我使用了模,而不是3874208490,我得到了一些其他的大正数。正确的方法是什么C++中的乘法溢出,c++,algorithm,overflow,C++,Algorithm,Overflow,在我的代码中,我尝试将两个数字相乘。算法很简单,如k*k-1^n。我将乘积k-1^n存储在变量p1中,然后将其与k相乘。对于n=10,k=10 k-1^n-1应该是387420489,我在变量p1中得到了这个值,但将其与k相乘后,我得到了一个负数。我使用了模,而不是3874208490,我得到了一些其他的大正数。正确的方法是什么 #include <iostream> using namespace std; typedef long long ll; ll big = 100
#include <iostream>
using namespace std;
typedef long long ll;
ll big = 1000000000 + 7;
ll multiply(ll a, ll b)
{
ll ans = 1;
for (int i = 1; i <= b; i++)
ans = ans * a;
return ans % big;
}
int main()
{
int t;
scanf("%d", &t);
while (t--)
{
ll n, k;
cin >> n >> k;
ll p1 = multiply(k - 1, n - 1);
cout << p1 << endl; // this gives correct value
ll p2 = (k % big) * (p1 % big);
cout << ((p2 + big) % big) % big << endl;
}
}
什么是ll型?如果它只是int,并且我很确定它是int,它就会溢出,因为32位有符号类型不能存储超过2^31-1的值,大约等于2*10^9。您可以使用long-long-int使其工作,然后您的代码将在小于2^63的结果下工作。出现溢出也就不足为奇了。我将你的方程插入wolfram alpha,将n固定在10,并在k上从0迭代到100
#include <iostream>
using namespace std;
typedef long long ll;
ll big = 1000000000 + 7;
ll multiply(ll a, ll b)
{
ll ans = 1;
for (int i = 1; i <= b; i++)
ans = ans * a;
return ans % big;
}
int main()
{
int t;
scanf("%d", &t);
while (t--)
{
ll n, k;
cin >> n >> k;
ll p1 = multiply(k - 1, n - 1);
cout << p1 << endl; // this gives correct value
ll p2 = (k % big) * (p1 % big);
cout << ((p2 + big) % big) % big << endl;
}
}
曲线非常垂直,在k=80左右时非常快
#include <iostream>
using namespace std;
typedef long long ll;
ll big = 1000000000 + 7;
ll multiply(ll a, ll b)
{
ll ans = 1;
for (int i = 1; i <= b; i++)
ans = ans * a;
return ans % big;
}
int main()
{
int t;
scanf("%d", &t);
while (t--)
{
ll n, k;
cin >> n >> k;
ll p1 = multiply(k - 1, n - 1);
cout << p1 << endl; // this gives correct value
ll p2 = (k % big) * (p1 % big);
cout << ((p2 + big) % big) % big << endl;
}
}
10^21需要70个二进制位来表示它,而在长字符串中只有63个二进制位
#include <iostream>
using namespace std;
typedef long long ll;
ll big = 1000000000 + 7;
ll multiply(ll a, ll b)
{
ll ans = 1;
for (int i = 1; i <= b; i++)
ans = ans * a;
return ans % big;
}
int main()
{
int t;
scanf("%d", &t);
while (t--)
{
ll n, k;
cin >> n >> k;
ll p1 = multiply(k - 1, n - 1);
cout << p1 << endl; // this gives correct value
ll p2 = (k % big) * (p1 % big);
cout << ((p2 + big) % big) % big << endl;
}
}
您必须确定此算法参数的限制,并选择相应的数据类型。也许双人房更合适
#include <iostream>
using namespace std;
typedef long long ll;
ll big = 1000000000 + 7;
ll multiply(ll a, ll b)
{
ll ans = 1;
for (int i = 1; i <= b; i++)
ans = ans * a;
return ans % big;
}
int main()
{
int t;
scanf("%d", &t);
while (t--)
{
ll n, k;
cin >> n >> k;
ll p1 = multiply(k - 1, n - 1);
cout << p1 << endl; // this gives correct value
ll p2 = (k % big) * (p1 % big);
cout << ((p2 + big) % big) % big << endl;
}
}
请使用正确的缩进。我使用的是模数-使用拼写检查器,更频繁地使用模数。遗憾的是,这看起来像是星期六的跳转。您已经对代码进行了宏化或typedefed,并将代码命名为几乎不可读取的变量。如果你打算从事软件开发工作,这是个坏主意,如果你想在代码混淆比赛中获胜,你必须更加努力。@Fredrarson很惊讶你的编辑与我将要发布的内容非常相似。@user4581301我只需要学习这个来解决一个编程竞赛问题。我假设它是一个long long的typedef。@Victor它是longlong@satya使用此类型进行检查,您可以阅读编号10000,然后写回。它的行为类似于32位有符号类型。@它仍然输出874208490。我需要在这段代码中做什么更改?