Комментарии 23
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
, что пришлось наделить переменную настолько интимным корнем, что я его даже обратно на русский и перевести-то стесняюсь?
Побитовая арифметика в Java