Проблема в реализации побитового вычитания UNIX C

введите сюда кодПроблема в реализации функции побитового вычитания. Проблема всегда начинается, когда идёт последовательность вычитания из 0 единицы.

В функциию всегда приходят положительные value_1 and value_2 , где value_1 > value_2.


    void make_sub(my_decimal value_1, my_decimal value_2, my_decimal *result) {
      memset(result, 0, sizeof(my_decimal));
      int carry = 0, diff;
      for (size_t i = L_BITS; i < MAN_BITS; ++i) {
        diff = get_bit(&value_1, i) - get_bit(&value_2, i) - carry;
        carry = (diff == -1) ? 1 : 0;
        if (abs(diff) == 1) set_bit(result, i);
      }
    }

В начале реализовывал вычитание через дополнительный код, но для моего типа данных это не подходит, так как отричательные числа от положительных отличается только установкой крайнего бита в положение 1.

Как иначе переписать функцию, чтобы та выполняла вычитание коректно и без костылей?


Как иначе реализовать пока не придумал.


Ответы (1 шт):

Автор решения: AlexGlebe

Не все ситуации у вас просчитаны.

Результат вычитаний может быть от -2 до 1.
Результат неправильно просчитывается при 0 - 1 - 1. carry должен быть с единицей, а бит нулю.

Подправим как в школе столбиком.
Добавляем 2 и ставим перенос.

void make_sub(my_decimal value_1, my_decimal value_2, my_decimal *result) {
      memset(result, 0, sizeof(my_decimal));
      int carry = 0, diff;
      for (size_t i = L_BITS; i < MAN_BITS; ++i) {
        if (get_bit(&value_1, i) >= get_bit(&value_2, i) + carry ) {
          diff = get_bit(&value_1, i) - get_bit(&value_2, i) - carry; 
          carry = 0;
        } else {
          diff = get_bit(&value_1, i) + 2 - get_bit(&value_2, i) - carry; 
          carry = 1;
        }
        if (diff)
          set_bit(result, i);
      }
    }
→ Ссылка