Jump to content

    

Сложение двух отрицательных чисел.

Recommended Posts

novikovfb
9 minutes ago, МАСТЕР LO said:

Тогда вот такой пример: берём 5 + 5 = 10,  знаковый разряд  0 числовые разряды 101, получаем 0101 + 0101 =  1010, в знаковом разряде переполнение

еще раз: увеличивайте разрядность и не потребуется никакой магии

Share this post


Link to post
Share on other sites

1 минуту назад, novikovfb сказал:

еще раз: увеличивайте разрядность и не потребуется никакой магии

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

Share this post


Link to post
Share on other sites

des00
43 minutes ago, МАСТЕР LO said:

Тогда вот такой пример: берём 5 + 5 = 10,  знаковый разряд  0 числовые разряды 101, получаем 0101 + 0101 =  1010, в знаковом разряде переполнение, результат ошибка, его пропускать нельзя.

вот у вас сразу ошибка. Берем ваш пример. 

число 5 в дополнительном коде, может быть уложено в 4 бита 0101. Но, диапазон представления любых знаковых чисел, в 4-х битах -8...+7.

Т.к. при сложении возможно переполнение, требуется выполнить знаковое расширение. А именно, представить число 5 в дополнительном коде с бОльшей разрядностью, чтобы не потерять возможное переполнение. Диапазон знаковых чисел в дополнительном коде, в 5 битах -16...+15. Это позволит отследить переполнение и не потерять результат. 

Итак, делаем знаковое расширение. Число 5 будет 00101. Выполняем вычисления 00101+00101 = 01010. Или +10. Всё. Что вы дальше будете делать с этим числом: оставить его в 5 битном формате с диапазоном -16..+15 или усечь его в 4-х битный диапазон -8...+7 решать вам. Но при усечении, нельзя терять монотонность. Т.к., как вы правильно заметили, результат сложения 5+5, при простом усечении будет 1010 или -6. Что противоречит логике здравого смысла. 

ЗЫ. Именно это и рассматривается в "Пример 1.14  СЛОЖЕНИЕ ЧИСЕЛ В ДОПОЛНИТЕЛЬНОМ КОДЕ С ПЕРЕПОЛНЕНИЕМ" в той самой книге:

Quote

Решение:  4 + 5 = 0100 + 0101 = 1001 =  –7. Результат не помещается в диапазон положительных четырехбитных чисел в дополнительном коде, оказываясь отрицательным. Если бы вычисление выполнялось с пятью или более битами, результат был бы такой 010012 = 910, что правильно. 

В случае необходимости увеличения количества битов произвольного числа, записанного в дополнительном коде, значение знакового бита 
должно быть скопировано в наиболее значимые разряды модифицированного числа. Эта операция называется знаковым расширением  (sign extension). Например, числа 3 и −3 записываются в 4-битном дополнительном коде как 0011 и 1101 соответственно. Если мы увеличиваем число разрядов до семи битов, мы должны скопировать знаковый бит в три наиболее значимых бита модифицированного числа, что дает 0000011 и 1111101. 

 

43 minutes ago, МАСТЕР LO said:

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

собираете обычный сумматор. Всё. Он может работать и в дополнительном коде со знаковыми числами и с беззнаковыми числами. Знаки/коды это всего лишь интерпретация результата. Само ядро сложения не изменяется. Обычно в процах делают тупой сумматор с расширением на 1 бит для бита переноса/знака. И вся обработка переполнений там программная. Если вам нужно сделать плисовый сумматор с обработками переполнений, то код я дал. Если просто сумматор с выходом переноса, ну вот этот + 1 бит это он и есть. 

Share this post


Link to post
Share on other sites

14 минут назад, des00 сказал:

собираете обычный сумматор

Спасибо и за код и за советы и подсказки. Однако всё дело в том, что в связи с санкциями не понятно, на каких ПЛИС в итоге  придётся делать устройство и в итоге аппаратных сумматоров может просто не хватить. А сама проблема выросла из необходимости сделать вычитание, а потом захотелось сделать блок, который складывал бы числа, а видя что числа отрицательные, автоматом вычислял бы их дополнительный код, и снова складывал, у получившегося результата если он получался бы в дополнительном коде вычислялось бы обычное число.  Хотелось сделать один раз один блок и навсегда о проблеме забыть. Как действовать я примерно понял, всем огромное спасибо, ещё раз спасибо за "умную книжку", а то учился давно и с этой темой после учёбы не пересекался.     

Share this post


Link to post
Share on other sites

des00
18 minutes ago, МАСТЕР LO said:

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

Да не нужно вам никакого вычисления дополнительного кода. В современном мире все знаковые числа представлены в дополнительном коде по умолчанию. Если там прямой или обратный код, то там отдельно это упоминается. У вас обычный многобитный сумматор: составленный  из полусумматора и полного сумматора. Все остальное интерпретация, для которого нужно знать бит carry результата (тот самый +1 бит). 

единственное, как мне кажется, когда вам может на ПЛИС понадобится преобразование из дополнительного в прямой код, это вычисление модуля числа. Если число отрицательное то нужно проксорить все биты и прибавить единицу. Чтобы не делать ветвление можно просто сделать так abs = data ^ {$bits(data){data[$high(data)]}} + data[$high(data)] но это не на всех плис разводится лучше чем вычитатель из нуля по условию

Share this post


Link to post
Share on other sites

40 minutes ago, des00 said:
40 minutes ago, des00 said:

 никакого вычисления дополнительного кода. В современном мире все знаковые числа представлены в дополнительном коде по умолчанию

 

В современном мире у меня такая ситуация: есть АЦП, выходной сигнал которого является заданием (он считывает напряжение с ручки задания), есть полная шкала времени,  вычитание задания полученного с АЦП даст искомый результат. Искомый результат тоже время, на которое будет открываться тиристор. Вот так устроен для меня современный мир.  А логика такая, чем больше задание, тем раньше нужно открывать тиристор, а значит нужно высчитать время паузы перед его открытием после прохода фазового напряжения через ноль. Заодно бывает неплохо что то прибавить или отнять по ходу пьесы.. 

Share this post


Link to post
Share on other sites

des00
10 minutes ago, МАСТЕР LO said:

есть АЦП, выходной сигнал которого является заданием (он считывает напряжение с ручки задания), есть полная шкала времени,  вычитание задания полученного с АЦП даст искомый результат. 

Настройки АЦП посмотрите. Если он знаковый, то там либо Offset Binary формат, что лечится обычным бинарным сложением с половиной шкалы и получаете 2's Complement, либо там уже 2's Complement что и есть дополнительный код. Если АЦП беззнаковый, то просто берете вашу рабочую точку и показания АЦП, расширяете на 1 бит нулями и вычитаете показания АЦП. Если рабочая точка == середина шкалы то добавлять 1 бит не надо. Это тот же самый Offset Binary 

Share this post


Link to post
Share on other sites

xvr

Немного занудства - в мире CPU знаковое переполнение вычисляется как исключающее или переноса ИЗ старшего разряда и В старший разряд

 

Share this post


Link to post
Share on other sites

sazh
4 часа назад, МАСТЕР LO сказал:

В современном мире у меня такая ситуация: есть АЦП, выходной сигнал которого является заданием (он считывает напряжение с ручки задания), есть полная шкала времени,  вычитание задания полученного с АЦП даст искомый результат. Искомый результат тоже время, на которое будет открываться тиристор. Вот так устроен для меня современный мир.  А логика такая, чем больше задание, тем раньше нужно открывать тиристор, а значит нужно высчитать время паузы перед его открытием после прохода фазового напряжения через ноль. Заодно бывает неплохо что то прибавить или отнять по ходу пьесы.. 

Чтоб к смыслу привязаться, имеет значение, какое входное напряжение подается на АЦП, которое не имеет понятия о числах со знаком или без знака. На выходе его по простому - код.

Например входной размах АЦП от 0В до 2В. Диапазон 2В. На  выходе диапазон кодов от 0000_0000 до 1111_1111. Далее все по ходу пьесы на сумматор, который не имеет понятия о числах со знаком или без знака. Если взять какой нибудь базовый примитив сумматора, то можно заметить что разрядная сетка как по входу, так и по выходу одна и та же, но есть выход переноса. В реальной жизни перенос не используют, сразу расширяют разрядную сетку сумматора как по входу (добавляют в старший разряд 0 к значению кода на выходе АЦП), так и по выходу. В результате во всем  диапазоне кодов с выхода АЦП   что при сложении кодов, что при вычитании кодов получаете правильный код, называете его число без знака. Дальше как то обрабатываете этот код (если надо поработать с разрядной сеткой).

Например входной  размах от -1В до +1 В.  Диапазон 2В. Этот размах приводят например к входному размаху АЦП (например от 0В до 2В, современные АЦП обычно запитываются от положительного напряжения). На выходе диапазон кодов  от 0000_0000 до 1111_1111. Но Вам говорят, что -1В хочу видеть как код 1000_0000, а +1В как код 0111_1111. 

Напрашиваются числа со знаком. Поэтому диапазон кодов на выходе АЦП от 0000_0000 по 1111_1111 преобразуют в диапазон кодов от 1000_0000 по 0111_1111.

В базовом примитиве сумматора, который не имеет понятия о числах со знаком или без знака задействуют  выход переполнения. В реальной жизни расширяют разрядную сетку, (по входу размножают уже старший бит кодов от 1000_0000 по 0111_1111. В результате во всем  диапазоне кодов с выхода АЦП   что при сложении кодов, что при вычитании кодов получаете правильный код, называете его число со знаком. Дальше как то обрабатываете этот код (если надо поработать с разрядной сеткой). Игра ума. Как то так.

Share this post


Link to post
Share on other sites

Уважаемые господа и дамы. Я очень благодарен всем, кто был со мной в это не простое для меня время написания этого модуля, за советы, подсказки, книжки и всё остальное. Всё написанное вами было в тему  и требовало осмысления. Осмысление наступило, равно как и тупиковый путь, рождённый блужданием глупой мысли. И вот у меня всё получилось. 12 битные + знак числа прекрасно складываются. (считай и вычитаются), по ходу пьесы, родился ещё блок сравнения чисел по модулю, который в проекте не пригодился, однако я решил его оставить, ибо полезная  в будущем получилась доп. функция.  Для всех кто помогал, а так же тех кому интересно прикрепляю здесь этот модуль. 

В модуле полно комментариев, что бы не запутаться в этом рабоче-крестьянском тексте. (модуль не 14, а 12 битовый)

Буду рад отзывам.

А ещё буду рад, если кто-то подскажет, что почитать и где посмотреть, как можно посчитать или промоделировать на нём задержки, (так вот сразу расписываюсь в беспомощности, т к ПЛИСами занимаюсь не так долго).

full_sum.v

Share this post


Link to post
Share on other sites

04.04.2022 в 14:23, andrew_b сказал:

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

 

Понимаю, тяжело, ну извините, пишу как умею. Но глаза портить конечно же не надо, если глазки устали - просто пройдите мимо. 

Share this post


Link to post
Share on other sites

sazh
04.04.2022 в 13:59, МАСТЕР LO сказал:

12 битные + знак числа прекрасно складываются. (считай и вычитаются)

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

Хоть числа со знаком, хоть числа без знака. Ему не хватает выходов переноса и переполнения. Только при расширении разрядной сетки можно говорить об правильных кодах как числа без знака unsigned, со знаком signed.

Непонятно, чем Вам не нравиться  a-b, a+b. Кстати прекрасную Вам книгу порекомендовали. Я полный сумматор себе так представил.

 

add_sub.v

Share this post


Link to post
Share on other sites

09.04.2022 в 11:17, sazh сказал:

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

Хоть числа со знаком, хоть числа без знака. Ему не хватает выходов переноса и переполнения. Только при расширении разрядной сетки можно говорить об правильных кодах как числа без знака unsigned, со знаком signed.

Непонятно, чем Вам не нравиться  a-b, a+b. Кстати прекрасную Вам книгу порекомендовали. Я полный сумматор себе так представил.

 

add_sub.v 1 kB · 2 скачивания

Огромное спасибо. Вы совершенно правы. Да, этот перенос в данном случае не реализован. Однако реализован выход "err", на котором при переполнении появляется "1" и некорректный результат отсекается, отдавая "нули" в разрядную сетку. Причина по которой это не сделано проста, мне некуда отдавать знак переполнения. А за книжку - ещё раз СПАСИБО! :)  Ваше замечание будет учтено :) , но на следующем этапе.  a-b, a+b - не нравится, так как в случае перехода с одной плис на другую не могу быть уверен, что при большом числе таких операций гарантированно будет хватать объёма кристалла. Могу быть в чём то не прав, т к занимаюсь ПЛИСами  пока совсем не долго.  Запустил Вашу программку, интересно. Обязательно погоняю.

Edited by МАСТЕР LO

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.