neo*_*003 12 c x86-64 integer-overflow addition extended-precision
我想获得在c中添加两个无符号64位整数的进位位。如果需要,我可以使用x86-64 asm。码:
#include <stdio.h>
typedef unsigned long long llu;
int main(void){
llu a = -1, b = -1;
int carry = /*carry of a+b*/;
llu res = a+b;
printf("a+b = %llu (because addition overflowed), carry bit = %d\n", res, carry);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
Joh*_*ger 10
作为@EugeneSh。观察到,进位为0或1。而且,由于a和b都具有相同的无符号类型,即使算术结果超出其类型范围,它们的总和也定义良好。此外,总和的(C)结果将小于两者,a并且b在发生溢出时将小于两者,否则将更大,因此我们可以使用以下事实:C关系运算的值等于0或1,以将进位表示为
carry = (a + b) < a;
Run Code Online (Sandbox Code Playgroud)
那不需要任何标题,也不依赖于特定的上限,甚至不依赖于a并且b具有相同的类型。只要两者都具有无符号类型,它就可以正确报告总和是否溢出它们较宽的类型或unsigned int(以较宽者为准),这与它们的总和设置进位相同。作为奖励,它是用总和本身来表示的,我认为可以清楚地说明正在测试什么。
进位可以是0或1。1如果有环绕,0否则。如果a + b > ULONG_LONG_MAX为true ,则发生环绕。请注意,这是数学上的问题,而不是C方面的问题,就好像a + b实际上是在溢出一样,这将不起作用。相反,您想将其重新排列为a > ULONG_LONG_MAX - b。因此,进位价值为:
carry = a > ULONG_LONG_MAX - b ? 1 : 0;
Run Code Online (Sandbox Code Playgroud)
或任何同等的首选样式。
limits.h。