Побитовое насыщенное сложение в C (HW) - PullRequest
7 голосов
/ 11 марта 2011

Я работаю над заданием и не могу понять, как это реализовать. Я должен сделать функцию sadd(int x, int y), которая возвращает числа, добавленные вместе, если только он не переполняется (затем просто возвращает максимально возможное значение int). Мне удалось предложить некоторые решения, включающие приведение и условные операторы, но они не разрешены в решении. Только операторы ~ ! ^ + << >> & и |.

Ответы [ 2 ]

6 голосов
/ 11 марта 2011

При добавлении чисел со знаком переполнение произошло, если вы добавили два числа с одинаковым знаком и получили результат с другим знаком. Из-за задействованных диапазонов невозможно создать переполнение при добавлении двух чисел разных знаков.

Итак, что вы можете сделать - наблюдать только за знаковым битом (самый старший из двух дополнений) - использовать исключающее ИЛИ, чтобы узнать, отличались ли два исходных числа по знаку, дополнить это так, чтобы вы получили ' 0 'если они разные,' 1 'для одного и того же.

Затем вы можете использовать исключающее ИЛИ для результата вместо одного из входов. Это даст «0», если они будут одинаковыми, «1», если они будут разными.

И эти два результата вместе, чтобы получить общее «1», если два входа были одинаковыми, но результат был разным, «0» в противном случае.

Затем вы можете использовать комбинацию сдвигов и OR для заполнения целого числа этим значением. Предположим, что вы используете 32-разрядное целое число, просто установите младшие 31 бит, чтобы получить положительное целое число с наибольшим значением. То, что вы можете затем сделать, это аналогичные наборы сдвигов и ИЛИ на знаковом бите любого из входов. Эксклюзив ИЛИ результаты. Вместо этого это даст наименьшее целое число, если входные данные были отрицательными.

РЕДАКТИРОВАТЬ: о, и использовать битовое значение того, было ли переполнение, расширенное, чтобы заполнить целое число, чтобы выбрать, какое значение вернуть, добавив к нему результат, который вы вернете, если будет переполнение, дополните его и добавьте и с нормальным аддитивным результатом, затем объединяя (или складывая) их вместе.

Presto: вся двоичная логика, без условий. Я полагаю, потому что это домашнее задание, что вам не нужен настоящий код?

0 голосов
/ 26 апреля 2019

С веб-сайта ARM о встроенных функциях:

4.1 Встроенные функции компилятора

Встроенные функции компилятора являются функциями, предоставляемыми компилятором.Они позволяют легко включать доменные операции в исходный код C и C ++, не прибегая к сложным реализациям на ассемблере.Языки C и C ++ подходят для широкого спектра задач, но они не обеспечивают встроенную поддержку для конкретных областей применения, например, для цифровой обработки сигналов (DSP).Внутри данного домена приложения обычно существует ряд специфичных для домена операций, которые необходимо часто выполнять.Однако часто эти операции не могут быть эффективно реализованы в C или C ++.Типичным примером является насыщенное сложение двух 32-разрядных целых чисел с двумя дополнительными числами со знаком, обычно используемых в программировании DSP.В следующем примере показана реализация C насыщенной операции добавления

#include <limits.h>
int L_add(const int a, const int b)
{
    int c;
    c = a + b;
    if (((a ^ b) & INT_MIN) == 0)
    {
        if ((c ^ a) & INT_MIN)
        {
            c = (a < 0) ? INT_MIN : INT_MAX;
        }
    }
    return c;
}

ARM Info Center

...