在 x + y 中获取"carry"
Getting "carry" in x + y
可能重复:
检测C/C++中整数溢出的最佳方法
如果我有一个表达式x + y
(在C或C++中),其中x
和y
都是导致整数溢出的uint64_t
类型,我如何检测它溢出了多少(进位),放在另一个变量中,然后计算余数?
假设使用的是无符号整数,则余数将存储在x+y的和中。无符号整数溢出导致环绕(有符号整数溢出未定义)。请参阅评论中Pascal的标准参考。
溢出只能是1位。如果你加上2个64位的数字,进位不能超过1个,所以你只需要检测溢出情况。
关于如何检测溢出,之前有一个关于该主题的问题:检测整数溢出的最佳方法。
对于z = x + y
,z存储余数。溢出只能是1位,而且很容易检测。如果处理有符号整数,那么如果x
和y
的符号相同,而z
的符号相反,则会出现溢出。如果x
和y
的符号不同,则不能溢出。对于无符号整数,您只需以相同的方式检查最高有效位。
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 < O2) { Rem = O2 - O1; Result = 0; } else { Rem = 0; Result = O1 - O2; }
)。
乘法有点困难:你最安全的选择是对值进行二进制乘法,并检查得到的值是否超过你的位数。二进制乘法是一种长乘法,就像你在纸上手工做十进制乘法一样,所以,例如,12*5是:
0110
0100
====
0110
0
0110
0
++++++
011110 = 40
如果你有一个四位整数,那么这里会有一位的溢出(即,位4是1,位5是0。因此只有比特4计数为溢出)。
对于除法,你只需要真正关心除以0,大多数时候——剩下的将由你的CPU处理。
HTH-
rlc
- C++为构建时间获取QDateTime的可靠方法
- lambda参数转换为constexpr技巧,然后获取带链接的数组
- 如何使用 < 和 > 命令获取 c++ 中的输入和输出?
- 使用指针从C++中的数组中获取最大值
- 如何获取std::result_of函数的返回类型
- 如何在openssl-ecc中获取十六进制格式的私钥
- 使用Unreal C++获取VR耳机的世界位置/方向
- 获取日期异步信号安全吗?如果在信号处理程序中使用,它会导致死锁吗
- 从C字符串中获取奇怪的字符串长度
- 为什么我的for循环不能正确获取argv
- 从python中调用C++函数并获取返回值
- 如何获取一个数字的前3位
- 获取字符串的长度并将其分配给数组
- 无法获取菜单选择以运行函数.C++
- 数组长度,为什么从命令行获取时不能使用它?
- Boost Spirit,获取迭代器内部语义动作
- 尝试通过OCI例程从Oracle获取blob数据,但出现错误:ORA-01008:并非所有变量都绑定
- 具有默认值的引用获取函数
- xmake总是报告:错误:无法获取cxx的程序,为什么
- 在 x + y 中获取"carry"