n %= m 是否可以为非常大的非负 n 和 m 返回负值
Can n %= m ever return negative value for very large nonnegative n and m?
这个问题是关于模运算符%
的。我们知道,一般来说,当 a 除以 b 并且余数大于或等于零且严格小于 b 时,a % b
返回余数。但是当a和b的星等为10^9时,上述情况是否成立?
我似乎得到了以下输入代码的负输出:
74 41 28
但是,更改最终输出语句可以完成工作,结果变得正确!
#include<iostream>
using namespace std;
#define m 1000000007
int main(){
int n,k,d;
cin>>n>>k>>d;
if(d>n)
cout<<0<<endl;
else
{
long long *dp1 = new long long[n+1], *dp2 = new long long[n+1];
//build dp1:
dp1[0] = 1;
dp1[1] = 1;
for(int r=2;r<=n;r++)
{
dp1[r] = (2 * dp1[r-1]) % m;
if(r>=k+1) dp1[r] -= dp1[r-k-1];
dp1[r] %= m;
}
//build dp2:
for(int r=0;r<d;r++) dp2[r] = 0;
dp2[d] = 1;
for(int r = d+1;r<=n;r++)
{
dp2[r] = ((2*dp2[r-1]) - dp2[r-d] + dp1[r-d]) % m;
if(r>=k+1) dp2[r] -= dp1[r-k-1];
dp2[r] %= m;
}
cout<<dp2[n]<<endl;
}
}
将最终输出语句更改为:
if(dp2[n]<0) cout<<dp2[n]+m<<endl;
else cout<<dp2[n]<<endl;
确实有效,但为什么需要它?
顺便说一句,代码实际上是我对这个问题的解决方案
由int
范围施加的限制。
int
只能保存介于 –2,147,483,648 到 2,147,483,647 之间的值。
考虑对 m、n、k、d 和 r 变量使用 long long
。如果可能,请使用unsigned long long
如果您的计算不应具有负值。
long long
可以保存 –9,223,372,036,854,775,808 到 9,223,372,036,854,775,807 之间的值
而unsigned long long
可以保存 0 到 18,446,744,073,709,551,615 之间的值。(2^64)
与无符号类型相比,有符号类型的正值范围大约减半,因为符号使用最高有效位;当您尝试分配大于指定数据类型所施加的范围的正值时,将引发最高有效位,并将其解释为负值。
嗯,不,具有正操作数的模不会产生负结果。
然而。。。。。
只有 C 标准保证 int 类型支持介于 -32767 到 32767 范围内的值,这意味着宏 m 不一定扩展到 int 类型的文本。 它将适合很长的时间(保证具有足够大的范围)。
如果发生这种情况(例如,具有 16 位 int 类型和 32 位长类型的编译器),取模运算的结果将被计算为尽可能长,并且可能具有超出 int 可以表示的值。 将该值转换为 int(就像 dp1[r] %= m 这样的语句一样,因为 dp1 是指向 int 的指针)会产生未定义的行为。
从数学上讲,大数字没有什么特别之处,但计算机只有有限的宽度来写下数字,所以当事情变得太大时,你会得到"溢出"错误。一个常见的类比是在汽车仪表板上行驶的英里数的计数器 - 最终它将显示为所有 9 并滚动到 0。由于负数的处理方式,标准有符号整数不会四舍五入为零,而是滚动到非常大的负数。
您需要切换到更大的变量类型,以便它们溢出的速度不那么快 - "long int"或"long long int"而不仅仅是"int",范围随着宽度每增加一点而加倍。您还可以使用无符号类型进一步加倍,因为负数没有使用范围。
- 函数作为模板参数,是否对返回类型强制约束
- lock_guard是否保护返回值
- 检查函数返回类型是否与STL容器类型值相同
- 将错误返回给调用方而不是立即在 C++ 中抛出错误是否是一种好的做法
- 返回指向对象的指针的函数调用是否为 prvalue?
- 是否所有C++运算符都返回一些内容
- 如果返回 -1,时间() 的参数是否被修改?
- 是否可以在 QAbstractItemModel 中返回正数行数和零列数?
- 当返回类型声明为 ListNode 时,我们是否可以返回 false<T>*
- 将 std::map::emplace 与返回 shared_ptr 的函数一起使用是否正确?
- C++方法是否可以根据传递给构造函数的参数具有不同的返回类型?
- 插入向量时,使用lambda的返回而不是函数的返回是否有意义?
- 默认情况下,返回是否使用移动或复制语义
- 在所有std::futures完成之前从函数返回是否安全
- 将成员函数指针强制转换为另一个类中的一个然后再返回是否安全
- 临时对象的成员函数的左值引用返回是否为悬空引用
- 通过引用成员变量EVER返回是否可接受
- 本例中引用静态变量的引用返回是否安全?
- 从 typeid 成功返回是否保证dynamic_cast不会引发异常?
- new 运算符 - 在C++中测试"new"的返回是否有用?