Как нормализовать сумму двух чисел одинарной точности IEEE754? - PullRequest
0 голосов
/ 14 декабря 2018

Я проектирую модуль с плавающей запятой в SystemVerilog, который принимает два 32-разрядных ввода в формате IEEE754, складывает их вместе и выводит результат в том же 32-разрядном формате IEEE754.

Мой вопросесть, как я могу определить, нужно ли нормализовать мой результат?

Я понимаю, что это когда вам нужно переместить «крайний левый» 1 в правильный бит, который должен быть битом 23 (начиная с бита 0)

Что у меня тяжеловремя, когда я оборачиваюсь, - это то, как я могу определить, какой правильный «самый левый» 1 бит, чтобы я мог сдвинуть мантиссу и соответственно увеличить / уменьшить биты экспоненты.

Если мое понимание верно, сложение должно иметьследующий процесс.

  • Разделите биты на знак, экспоненту и мантиссу
  • Добавьте «1» к мантиссе
  • Сравните показатели и добавьте разницу кменьший показатель
  • Сместить мантиссу меньшего показателя вправо на указанное различие, чтобы правильно «выстроить» десятичные дроби / число
  • Выполнить двоичное сложение
  • Нормализовать результат, еслинеобходимо

Я полагаю, что у меня есть все шаги, кроме нормализующей части, правильной.Моя проблема в том, как я могу определить, что результат не нормализован, если все, что у меня есть, это биты?

Я знаю, что он не нормализован, если результат не равен 1. (дробь).
т.е.10.10101 * 2 ^ 1 должно быть нормализовано до 1.010101 * 2 ^ 2, а .1001 * 2 ^ 2 должно быть нормализовано до 1.001 * 2 ^ 1.

В частности, я думаю, я пытаюсь спросить, как я могуотслеживать, где находится «десятичное» место после добавления двух чисел.

Например: Добавление ввода a: 0x3fc00000 (1.5) и b: 0x40500000 (3.25)

a = 0 |0111 1111 |(1) 100 0000 0000 0000 0000 0000
b = 0 |1000 0000 |(1) 101 0000 0000 0000 0000 0000

показатель степени a меньше b на разницу 1, поэтому:

a = 0 |1000 0000 |0 (1) 10 0000 0000 0000 0000 0000
b = 0 |1000 0000 |(1) 101 0000 0000 0000 0000 0000

добавление мантисс даст нам результат

1 0011 0000 0000 0000 0000 0000

Здесь мы видим «крайний левый»1 является битом 24, а не 23, поэтому мы смещаем мантиссу вправо на 1 и увеличиваем показатель степени для нормализации результата.Затем мы удаляем «самый левый» 1, поскольку он подразумевается в формате IEEE754, и мы получаем:

0 |1000 0001 |001 1000 0000 0000 0000 0000 (4.75) в качестве нашего конечного результата, который является правильным.

Учитывая этот пример, я подумал, что мне просто нужно проверить следующие случаи:

  • Еслибит 24 мантиссы равен 1, сдвиг мантиссы вправо и показатель приращения
  • Иначе контрольный бит 23 равен 1, если true, нормализация не требуется
  • Иначе контрольный бит 22 равен 1, затем сдвиг мантиссылевая и убывающая экспонента

Однако я нахожу это верным только в некоторых случаях.Чего мне не хватает?

В моей реализации я сделал 26-битное значение для хранения суммы двух мантисс, что, я не уверен, является правильным.Бит 25 является признаком мантиссы, которая, на самом деле, мне не нужна, а биты 24 и 23 - это скрытые биты, или биты, которые не будут включены в окончательный вывод.

Например: 0x449ebbc8 (1269.868163) + 0xc60eb709 (-9133.758561) дает мне следующую мантиссу:

11 0111 1010 1101 1111 1001 0000 обратите внимание, что это 26 бит (25: 0)

Если бы я следовал предыдущему случаю, это означало бы, что «крайний левый 1» бит, исключая знаковый бит, был бы битом 24, что означало бы смещение мантиссы вправо и увеличение экспоненты.Однако правильный ответ противоположен!«Истинный» крайний левый 1 бит - это бит 22!Это означает, что я должен сместиться влево и уменьшить вместо этого!Дайте мне окончательный результат:

1 |10001011 |111 0101 1011 1111 0010 0000 (-7863,8906), что правильно.

Аналогично, добавление 0x45c59cbd и 0xc473d9dc дает мантиссе

01 1010 0111 0010 0001 1000 0010, но бит «крайний левый 1» - это не бит в 24, а в бите 23, поэтому нормализация не требуется.

Почему в первом случае янужно беспокоиться о бите 24, но не о двух других случаях?Это потому, что я добавляю противоположные знаки для других случаев?Проблема переполнения?Или есть что-то еще, чего я в принципе упускаю?

Спасибо за помощь и извините, если форматирование плохое!

1 Ответ

0 голосов
/ 14 декабря 2018

Попробуйте добавить два положительных нормальных числа в базовом 32-разрядном двоичном формате IEEE-754.Когда их значения 1 завершаются префиксом старшего бита, смещением для выравнивания показателей степени и добавлением, ведущий бит находится либо в той же позиции (потому что не было переноса), либо влево (потому чтонести произошло).Чтобы нормализовать это, просто сдвиньте один бит вправо, если произошел перенос.

(Если оба числа являются ненормальными, старший бит может быть дальше вправо. Однако нормализация не будет выполнена, так как результат либо переноситсяв положение, которое делает его нормальным [таким образом, нормализация не требуется] или не переносится в это положение [таким образом, результат все еще является ненормальным и не может быть нормализован].)

Если оба числа отрицательны, то такая же ситуациядержит.Значения можно рассматривать как абсолютные значения, игнорируя знаковые биты.

Если число имеет противоположные знаки, возникают сложности.Вопрос описывает добавление префикса к значению.Это не приведет к правильному результату.Например, рассмотрите возможность добавления +1.125 и -1.125.Четырехразрядное значение каждого числа равно 1001. Префикс префиксных битов дает нам 01001 и 11001 соответственно.Затем добавление этих значений дает 1 00010 (новая крайняя левая цифра получается из предыдущей крайней левой позиции).Независимо от того, как мы относимся к старшим битам, младшие биты неверны - 0010 не правильно;так как +1.125 + -1.125 = 0, результат должен быть 0000 с некоторым знаком.Так что просто добавление префиксом бита знака к значениюи не является правильной процедурой.

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

В этой модели определяется, как нормализоватьчисло становится проще:

  • При добавлении чисел с одинаковыми знаками нормализация требует смещения правого нуля или одного бита в зависимости от того, был ли перенос с высокой позиции.(Обратите внимание, что может произойти переполнение экспоненты.)
  • При вычитании чисел с противоположными знаками нормализация требует сдвига влево до тех пор, пока старший бит не окажется в правильной позиции или не будет достигнут минимальный показатель степени.

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

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

Сноска

1 «Значение» - предпочтительный термин для дробной части плавающегономер точки.«Мантисса» является историческим термином для дробной части логарифма.Значения являются линейными (удваивает значение и удваивает представленное значение), в то время как мантиссы являются логарифмическими (удвоение мантиссы возводит в квадрат часть значения, которое оно представляет).

...