Как стать автором
Обновить

Комментарии 23

В вычитании для дополнительного кода -x = not x +1. not вижу а +1 не видно.
Предполагается только инверсия, но не дополнительный код, иначе работать не будет.
Я вас не понял. У вас алгоритм сложения и вычитания одинаковые. Одинаковый алгоритм возможен только для чисел в дополнительном коде. В вычитании вы теряете +1, и сейчас, насколько я понимаю, результат неправильный даже для положительных чисел.
Они практически одинаковые, разница лишь в инверсии.
m = 3
0011
s = 2
0010

b	=~m & s
0000 = 1100 & 0010

m	= m ^ s
0001 = 0011 ^ 0010

s	= b << 1
0000 = 0000 << 0001

return m (0001)

Приношу извинения, что не раскрыл этот абзац в статье.
Спасибо. Я разобрался. У вас классическое побитовое вычитание.
ЗЫ Лучше убрать упоминание про вычитание, как сложение с отрицательным знаком. Это к вашему алгоритму никакого отношения не имеет вообще. Меня это полностью запутало.
ЗЫЗЫ Лучше написать что перенос при сложении, это когда биты одинаковые, а заем при вычитании это когда инверися обратной импликации.
Понял, благодарю, удаляю!)
Все таки стоит упомянуть что заем это инверсированая обратная
импликация.
Она действительно вычисляется как ((not a) and b). Поэтому здесь not — часть вычисления импликации, и отдельного смысла в нем нет.
Исправил)
Ну, битовые операции сами по себе весьма фундаментальная вещь.
Ну, например, может пригодиться для обфускации кода каких-нибудь алгоритмов защиты

Нда. Начнем со сложения. Почему на входе два аргумента и на выходе один результат?
Собственно вот тут: https://m.habr.com/ru/post/455312/
расписана правильная реализация однобитного сумматора, у нее на входе: три аргумента: два слагаемых и бит переноса, на выходе два результата: сумма и перенос.

Потому, что это программная реализация, а не аппаратная.

Неважно какая реализация. Суть однобитного сумматора в том что его можно каскадировать и обрабатывать N битные числа. Каскадирование в вашей реализации — невозможно, отсюда вопрос накой она нужна?

Еще как важно.
Вы предлагаете подавать на вход три аргумента, получать на выходе два. Вы часто имеете дело с таким калькулятором?

Еще раз для «внимательных»: задача — побитовый АНАЛОГ арифметических операций, а не СУММАТОР.
Нужно было бы реализовать схему из вашей ссылки, то поверьте, я бы этим и занялся.
Эти алгоритмы прекрасно работает с заданными диапазонами, достаточно указать цлевой тип.
Прежде чем вывалить здесь свое безапелляционное «фи», для приличия, хотя бы, копи-пастнице исхоник.
Вы часто имеете дело с таким калькулятором?

Постоянно. Оно на уровне регистров АЛУ именно так и работает.


Еще раз для «внимательных»: задача — побитовый АНАЛОГ арифметических операций …

Только два бита складывать? и зачем такой калькулятор нужен?

Алгоритм умножения у вас с ошибкой. При умножение чисел больше чем INT_MAX /2 значащие биты при сдвиге mul1 будут теряться. Надо было сначала перевести в long.
И ещё — это только умножение неотрицательных чисел. Отрицательные умножаются по другому.

Отнюдь.
Для проверки откройте стандартный калькулятор Windows, установите размер слова в DWORD (эквивалентно 32 битам) и умножение 2147483647 * 2 = -2; да, по причине целочисленного переполнения, но в статье я указывал, что у меня нет long (работа с устройствами с ограниченными ресурсами).

Умножение отрицательных значений проверено, отточено, выстрадано)
Вероятно, вы его спутали с тем, в котором while(mul2 > 0) — там да, необходимо получение абсолютных значений и сохранение знака, а инструкция возвращения будет выглядеть так: return result * sign;
Есть очень хорошая книжка по алгоритмам — Злобин В. К., Григорьев В. Л. — Программирование арифметических операций в микропроцессорах.
Кстати, насколько я поримаю, деление и умножение побитовые очень медленные. В железе тоже используют алгоритмы с таблицами а не с битами.
Благодарю за рекомендацию, обязательно ознакомлюсь с этим трудом! Просто моя задача была не в программировании микропроцессора, а проверка на корректность работы заложенных в него арифметических операций.
есть одно исключение — это максимально большое отрицательное число заданного типа

Вот-вот. До сих пор раздражает что в Java не завезли unsigned…

subtrahend

А что было не так с subtract, что пришлось наделить переменную настолько интимным корнем, что я его даже обратно на русский и перевести-то стесняюсь?

:)
У меня нет достаточных познаний в английском, особенно в арифметической терминологии, потому, на всякий случай, я сверялся с multitran.com, согласно которому:
minuend — уменьшаемое;
subtrahend — вычитаемое;
subtract — гл. вычитать;
Зарегистрируйтесь на Хабре , чтобы оставить комментарий

Публикации

Истории