12

我想获得在 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;
}
4

2 回答 2

9

作为@EugeneSh。观察到,进位是 0 或 1。此外,鉴于ab都具有相同的无符号类型,即使算术结果超出了它们的类型范围,它们的总和也得到了很好的定义。此外,当发生溢出时,求和的 (C) 结果将小于两者ab,否则更大,因此我们可以使用 C 关系运算评估为 0 或 1 的事实将进位位表示为

carry = (a + b) < a;

这不需要任何标题,也不依赖于特定的上限,甚至不依赖于ab具有相同的类型。只要两者都具有无符号类型,它就会正确报告总和是否溢出其类型中较宽的类型或unsigned int(以较宽者为准),这与它们设置进位位的总和相同。作为奖励,它以总和本身表示,我认为这清楚地表明了正在测试的内容。

于 2019-05-07T17:20:38.683 回答
8

进位只能是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.
于 2019-05-07T17:14:01.953 回答