Получить без знака длинное длинное сложение

Я хочу получить дополнительный бит добавления двух беззнаковых 64-битных целых чисел в c. Я могу использовать 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 ответа

Решение

Как @EugeneSh. отмечает, что перенос равен 0 или 1. Более того, учитывая, что a а также b оба имеют одинаковый тип без знака, их сумма четко определена, даже если арифметический результат превышает диапазон их типа. Кроме того, результат (C) суммы будет меньше, чем оба a а также b когда происходит переполнение, и больше в противном случае, поэтому мы можем использовать тот факт, что реляционные операции C оцениваются либо в 0, либо в 1, чтобы выразить бит переноса как

carry = (a + b) < a;

Это не требует каких-либо заголовков и не зависит от конкретной верхней границы или даже от a а также b имея тот же тип. Пока оба имеют неподписанные типы, он правильно сообщает о том, переполняет ли сумма более широкий их тип или unsigned int (в зависимости от того, что шире), что совпадает с их суммой, устанавливающей бит переноса. В качестве бонуса он выражается в терминах самой суммы, которая, я думаю, дает понять, что тестируется.

Носить можно только 0 или же 1, 1 если бы было обтекание и 0 иначе. Обертка происходит в случае, если a + b > ULONG_LONG_MAX правда. Обратите внимание, что это в математических терминах, а не в терминах C, как если бы a + b на самом деле переполнен, то это не будет работать. Вместо этого вы хотите, чтобы это было a > ULONG_LONG_MAX - b, Таким образом, стоимость переноса будет:

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

или любой предпочтительный эквивалент стиля.

  • Не забудьте включить limits.h,
Другие вопросы по тегам