Pull to refresh

Comments 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 — гл. вычитать;
Sign up to leave a comment.

Articles