Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/wix/2.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++ 数字在[10^5,10^10]范围内的无符号长溢出_C++_Integer Overflow - Fatal编程技术网

C++ 数字在[10^5,10^10]范围内的无符号长溢出

C++ 数字在[10^5,10^10]范围内的无符号长溢出,c++,integer-overflow,C++,Integer Overflow,我在《应用密码学手册》(http://cacr.uwaterloo.ca/hac/about/chap2.pdf-algorithm 2.143)一书中实现了用于求幂的重复平方和乘法算法,该算法计算出(A^k)mod n。 数字a、k和n的范围为[10^5,10^10] 代码是有效的,但有些情况下似乎出现了溢出,我不知道为什么,因为10^10>移位)!=0)移位++; f=a; //二进制移位以提取位置0的位值 如果((k>>0)&1)==1) b=a; 对于(int i=1;i>i)&1)==

我在《应用密码学手册》(http://cacr.uwaterloo.ca/hac/about/chap2.pdf-algorithm 2.143)一书中实现了用于求幂的重复平方和乘法算法,该算法计算出(A^k)mod n。 数字a、k和n的范围为[10^5,10^10]

代码是有效的,但有些情况下似乎出现了溢出,我不知道为什么,因为10^10<2^63-1

一种特殊的错误情况: a=3807869923;k=1735393391;n=6748918117

结果应该是65(),但代码返回2608265009

代码:

/*此函数计算(a^k)模n。
它实现了《应用密码学手册》中的算法2.143*/
{
整数移位=0;
无符号长b,f;
b=1;
如果(k==0)返回b;
//获取数字k的位数
而((k>>移位)!=0)移位++;
f=a;
//二进制移位以提取位置0的位值
如果((k>>0)&1)==1)
b=a;
对于(int i=1;i>i)&1)==1)
b=((f%n)*(b%n))%n;
}
返回b;
}

在以下代码行中:

f = ((f%n)*(f%n)) % n;
你可以自己多个
n-1
n
可以大到
10^10
,这意味着
(n-1)^2
几乎可以是
10^20
溢出
2^63-1


正如巴拉克·马诺斯(barak manos)在下面的评论中指出的那样,你使用的是“unsigned long long long”,这意味着限制是
2^64-1
,而不是
2^63-1
。但是,这并不能改变问题。

不要链接到代码。如果代码长,就把它删掉。然而,对于
n=6748918117
,如示例中所述,
(n-1)(n-1)=0x781AA1D967006F10<0x7FFFFFFFFFFFFF=2^63-1
(更不用说限制实际上是
2^64-1
)。它是0x2 781A A1D9 6700 6F10(为可读性而添加的空格),因为您可以看到它已经溢出了。@icepack:Hmmmm…谢谢(顺便说一句,这是Windows calc,不是我的)
f = ((f%n)*(f%n)) % n;