Добавление 32-битных чисел с плавающей точкой. - PullRequest
3 голосов
/ 25 октября 2011

Я узнаю больше, чем когда-либо хотел узнать о числах с плавающей точкой.

Допустим, мне нужно добавить:

1 10000000 00000000000000000000000

1 01111000 11111000000000000000000

* Форма дополнения 1008 * 2.

Первый битэто знак, следующие 8 битов - это показатель степени, а последние 23 бита - это богомол.

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

какие-нибудь хорошие ресурсы для этого материала?Видео и примеры практики были бы отличными.

1 Ответ

6 голосов
/ 25 октября 2011

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

О, да, и если это разные знаки, вы просто вместо этого вызываете свою функцию вычитания: -)

Давайтесделайте пример в десятичном виде, так как это легче понять.Предположим далее, что они хранятся только с восемью цифрами справа от десятичной дроби (а числа находятся в диапазоне от 0 включительно до 1 исключающей).

Добавьте два числа:

sign  exponent  mantissa  value
   1        42  18453284  + 0.18453284 x 10^42
   1        38  17654321  + 0.17654321 x 10^38

Масштабирование этих чисел до наивысшего показателя дает кое-что, где вы можете добавить поля мантиссы.Это также иллюстрирует, как точность может быть потеряна из-за сдвига.Например, IEEE754 с плавающей запятой одинарной точности будет иметь:

1e38 + 1e-38 = 1e38

, например, с:

#include <stdio.h>
int main (void) {
    float f1 = 1e38;
    float f2 = 1e-38;
    float f3 = f1 + f2;
    float f4 = f1 - f3;
    printf ("%.50f\n", f4);
    return 0;
}

С точки зрения того, что происходит с переполнением, это часть упомянутой мной нормализации,Давайте добавим 99999.9999 к 99999.9993.Поскольку у них уже есть один и тот же показатель степени, не нужно масштабировать, поэтому мы просто добавляем:

sign  exponent  mantissa  value
   1         5  99999999  + 0.99999999 x 10^5
   1         5  99999993  + 0.99999999 x 10^5
   =        ==  ========
   1         5 199999992  ???

Здесь вы можете видеть, что у нас есть ситуация переноса, поэтому мы не можем поместить этот перенос в число, будучиограничено до восьми цифр.Затем мы смещаем число вправо, чтобы мы могли вставить перенос.Поскольку этот сдвиг фактически делится на десять, мы должны увеличивать показатель степени, чтобы противостоять этому.

Итак:

sign  exponent  mantissa  value
   1         5 199999992  ???

становится:

sign  exponent  mantissa  value
   1         6  19999999  + 0.19999999 x 10^6

В действительности это не просто сдвиг вправо, поскольку вам нужно округлить до ближайшего числа.Если число, которое вы выводите, составляет пять или более, вам нужно добавить его к цифре слева.Вот почему я выбрал 99999.9993 в качестве второго числа.Если бы я добавил 99999.9999 к себе, я бы получил:

sign  exponent  mantissa  value
   1         5 199999998  ???

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

sign  exponent  mantissa  value
   1         6  20000000  + 0.2 x 10^6
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...