Вы должны масштабировать числа так, чтобы они имели одинаковый показатель степени.Затем вы добавляете поля мантиссы и, если необходимо, нормализуете результат.
О, да, и если это разные знаки, вы просто вместо этого вызываете свою функцию вычитания: -)
Давайтесделайте пример в десятичном виде, так как это легче понять.Предположим далее, что они хранятся только с восемью цифрами справа от десятичной дроби (а числа находятся в диапазоне от 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