长期未加签名

时间:2019-05-07 17:05:18

标签: c x86-64 addition integer-overflow 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;
}

2 个答案:

答案 0 :(得分:10)

@EugeneSh。观察到,进位为0或1。此外,假设ab都具有相同的 unsigned 类型,即使算术结果超过其类型的范围。此外,总和的(C)结果在发生溢出时将小于ab,否则将大于carry = (a + b) < a; a,因此我们可以利用C关系运算的结果为0或1的事实将进位表示为

b

这不需要任何标头,也不依赖于特定的上限,甚至不依赖于具有相同类型的unsigned intPOST /repos/:owner/:repo/pulls 。只要两者都具有无符号类型,它就会正确报告总和是否溢出其类型中的较宽类型或 { "title": "Amazing new feature", "body": "Please pull this in!", "head": "theOwner:new-branch", "base": "master" } (以较宽者为准),这与它们的总和设置进位相同。作为奖励,它是用总和本身来表示的,我认为可以清楚地说明正在测试什么。

答案 1 :(得分:7)

Carry只能是011(如果有环绕),否则为0。 如果a + b > ULONG_LONG_MAX为true,则发生环绕。请注意,这是数学上的问题,而不是C方面的问题,好像a + b实际上溢出了,那么这将行不通。相反,您想将其重新排列为a > ULONG_LONG_MAX - b。因此进位值将是:

carry = a > ULONG_LONG_MAX - b ? 1 : 0;

或任何等效的首选样式。

  • 别忘了包含limits.h