Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/unity3d/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 对于非常大的非负n和m,n%=m是否可以返回负值?_C++_Operators_Largenumber - Fatal编程技术网

C++ 对于非常大的非负n和m,n%=m是否可以返回负值?

C++ 对于非常大的非负n和m,n%=m是否可以返回负值?,c++,operators,largenumber,C++,Operators,Largenumber,这个问题是关于模运算符%。我们知道,通常a%b在a除以b且余数大于或等于零且严格小于b时返回余数。但当a和b的震级为10^9时,上述情况是否成立 对于以下输入代码,我似乎得到了负输出: 74 41 28 但是,更改最终输出语句会起作用,并且结果会变得正确 #include<iostream> using namespace std; #define m 1000000007 int main(){ int n,k,d;

这个问题是关于模运算符
%
。我们知道,通常
a%b
在a除以b且余数大于或等于零且严格小于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;
        }
   }
#包括
使用名称空间std;
#定义m 100000007
int main(){
int n,k,d;
cin>>n>>k>>d;
如果(d>n)

cout这是由
int
范围施加的限制

int
只能保存介于-21474836482147483647之间的值

考虑对m、n、k、d&r变量使用
long-long
。如果您的计算不应该有负值,请尽可能使用
unsigned long-long

long-long
可以保存从-92233720368547758089223372036854775807的值

无符号long-long
可以保存018446744073709551615之间的值(2^64)


与无符号类型相比,有符号类型的正值范围大约减少了一半,这是因为最高有效位用于符号;当您尝试分配大于指定数据类型所施加范围的正值时,最高有效位将升高,并被解释为负值

从数学上讲,大数字并没有什么特别之处,但计算机只有有限的宽度来记录数字,所以当事情变得太大时,就会出现“溢出”错误。一个常见的类比是汽车仪表板上行驶英里数的计数器-最终它将显示为所有9并转为0。由于负数的处理方式,标准有符号整数不会转为零,而是转为非常大的负数


您需要切换到更大的变量类型,以便它们溢出的速度更快——“long int”或“long long int”而不仅仅是“int”,范围每增加一个宽度位就加倍。由于没有范围用于负数,因此也可以使用无符号类型进行进一步加倍。

嗯,不,正操作数的模运算不会产生负结果

然而

int类型仅由C标准保证支持范围为-32767到32767的值,这意味着您的宏m不一定要扩展为int类型的文本。它将适合较长的范围(保证有足够大的范围)


如果发生这种情况(例如,具有16位int类型和32位long类型的编译器),则模运算的结果将被计算为long,并且可能具有超过int所能表示的值。将该值转换为int(由于dp1是指向int的指针,dp1[r]]=m等语句将需要此值)提供未定义的行为。

可以容纳
int
long
的值是实现定义的,并且变化很大。如果您尝试分配超出范围的值,结果是实现定义的;您不一定会得到负值……但是,好的编译器会发出警告。遗憾的是,许多新程序员用于忽略它们,因为“它们不是错误,对吗?”IIRC:不适合的转换结果是实现定义的,而不是未定义的行为。(不适合的操作的结果是未定义的行为,但这不能发生在
%
中)
        if(dp2[n]<0) cout<<dp2[n]+m<<endl;
        else cout<<dp2[n]<<endl;