C++ 获得;携带;在x+;Y
可能重复:C++ 获得;携带;在x+;Y,c++,c,math,C++,C,Math,可能重复: 如果我有一个表达式x+y(C或C++),其中x和y都是导致整数溢出的类型uint64\u t,我如何检测它溢出了多少(进位),放置在另一个变量中,然后计算余数?假定您使用的是无符号整数,则余数已存储在x+y的和中。无符号整数溢出导致环绕(无符号整数溢出未定义)。请参见注释中Pascal的标准参考 溢出只能是1位。如果添加2个64位数字,则进位不能超过1位,因此只需检测溢出情况 关于如何检测溢出,之前有一个关于该主题的问题:。对于z=x+y,z存储剩余部分。溢出只能是1位,很容易检测
如果我有一个表达式
x+y
(C或C++),其中x
和y
都是导致整数溢出的类型uint64\u t
,我如何检测它溢出了多少(进位),放置在另一个变量中,然后计算余数?假定您使用的是无符号整数,则余数已存储在x+y的和中。无符号整数溢出导致环绕(无符号整数溢出未定义)。请参见注释中Pascal的标准参考
溢出只能是1位。如果添加2个64位数字,则进位不能超过1位,因此只需检测溢出情况
关于如何检测溢出,之前有一个关于该主题的问题:。对于
z=x+y
,z存储剩余部分。溢出只能是1位,很容易检测。如果处理有符号整数,那么如果x
和y
具有相同的符号,但z
具有相反的符号,则会出现溢出。如果x
和y
具有不同的符号,则不能溢出。对于无符号整数,你只需用同样的方式检查最有效的位。 < P> C和C++中的方法可以完全不同,因为在C++中,你可以为操作符重载工作,并将你想要保护的整数包在某类中。在C中,必须将要保护的整数包装在一个结构中(以携带余数和结果),并调用一些函数来执行重载
除此之外,这两种语言的方法是相同的:根据您想要执行的操作(在您的示例中添加),您必须找出可能发生的最坏情况并加以处理
在加法的情况下,它非常简单:如果两个操作数的和大于某个最大值(如果最大值M
和其中一个操作数的差大于另一个操作数,就会出现这种情况),则可以计算余数-太大的部分:if((M-O1)>O2)R=O2-(M-O1)
(例如,如果M
为100,O1
为80,O2
为30,30-(100-80)=10,这是余数)
减法的情况同样简单:如果第一个操作数小于第二个操作数,则余数是第二个操作数减去第一个操作数(if(O1
)
乘法有点困难:最安全的方法是对值进行二进制乘法,并检查结果值是否超过已有的位数。二进制乘法是一种长乘法,就像在纸上手工进行十进制乘法一样,例如,12*5是:
0110
0100
====
0110
0
0110
0
++++++
011110 = 40
如果您有一个四位整数,这里会有一位溢出(即第4位是1,第5位是0。因此只有第4位算作溢出)
对于除法,您实际上只需要关心0的除法,大多数情况下-其余部分将由您的CPU处理
嗯
rlc同意,测试溢出条件的最简单方法是,当出现溢出时,加法的结果正好<到其中一个参数上。很好,也很快!谢谢。@克拉克只有带符号的溢出在C中是未定义的(可能在C++中也是如此)。无符号溢出被指定为给出结果模(可表示的最大整数+1)。C99 6.2.5.9:“涉及无符号操作数的计算永远不会溢出,因为无法由结果无符号整数类型表示的结果将按大于结果类型可表示的最大值一的数字进行模化处理。”丹尼尔:整数溢出在C和C++中是不确定的。如果X+Y溢出,Z有一个未定义的值,而不是剩余的。NVM我好像已经说谎了。谢谢!符号整数溢出是未定义的,这意味着你必须提前检测它,避免溢出计算,就像你用除法除法一样。顺便说一句:我假设你想检测溢出并进行诊断。