Получить без знака длинное длинное сложение
Я хочу получить дополнительный бит добавления двух беззнаковых 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
,