#cpu-architecture
#cpu-architecture
Вопрос:
У меня есть вопрос о добавлении двух чисел с плавающей запятой в двоичном коде. Кто-нибудь может сказать мне, какой шаг я сделал неправильно?
Ниже приведены два числа с плавающей запятой
sign exponent fraction
1 11101101 10000001101000011010011
0 11101110 01010100001001110010110
Первый шаг. выровнять показатель степени (необходимо выровнять по большому)
1 11101110 11000000110100001101001 (exponet 1 and shift right)
0 11101110 01010100001001110010110
Второй шаг. округление (потому что я сдвигаю вправо и игнорирую число = 1/2, а младший значащий бит равен 1, поэтому нам нужно добавить 1)
PS: это правило округления находится на видео https://www.youtube.com/watch?v=wbxSTxhTmrs когда 9:33
Третий шаг. сложение (для дробной части)
1.01010100001001110010110
- 0.11000000110100001101010 (add 1 for rounding up)
-------------------------------------------
1.00100110101011001011000
Последние
потому 1.00100110101011001011000
что нормализовано, поэтому дробь 00100110101011001011000
равна, а показатель равен 11101110
но ответ в экспоненте 11101101
равен, а дробь равна 00100110101011001011001
есть ли какие-либо ошибки в каждом моем шаге? Спасибо.
Комментарии:
1. Не являются ли оба показателя отрицательными — поэтому второй должен быть выровнен с первым (т. Е. Который является наибольшим / наименьшим отрицательным)?
Ответ №1:
В ваших вычислениях есть несколько ошибок, в основном из-за забывания скрытых битов и выполнения вычислений с неправильным количеством битов.
A:1 11101101 (1).10000001101000011010011
B:0 11101110 (1).01010100001001110010110
Шаг 1:
Добавить скрытые биты
Выравнивание показателей
Переход к представлению дополнения two
Обратите внимание, что при замене абсолютного значения знака на дополнение 2 вам понадобится один дополнительный бит.
A=exp(11101110) -(00.110000001101000011010011)
=exp(11101110) 11.001111110010111100101101
B=exp(11101110) 01.01010100001001110010110
Шаг 2: выполните сложение
Поскольку у вас может быть результат> 1 (или (<-2), это должно быть сделано с дополнительным битом со знаком расширения операндов. Вы не должны выполнять округление операнда раньше. Если операнды близки и имеют разный знак, вы можете потерять бит (ы) точности.
(ca) 11 11111 1 1111 1 11
111.001111110010111100101101
001.01010100001001110010110
-----------------------------
000.100100110101011001011001
Шаг 3: перенормируйте, чтобы получить число от 1 до 2, отрегулируйте показатель степени и преобразуйте число в знак абсолютного представления.
m=1.00100110101011001011001 exp=exp-1=11101101
Шаг 4: Округлите результат и перенормируйте, если требуется.
(здесь нечего делать).
Итак, m = (1) .00100110101011001011001 exp = 11101101
Это дает ожидаемый результат. И можно перепроверить.
#include <stdio.h>
int main(){
union floatint {
int i;
float f;
};
union floatint a;
a.i=0xf6C0D0D3;// 1111 0110 1100 0000 1101 0000 1101 0011
union floatint b;
b.i=0x772A1396;// 0111 0111 0010 1010 0001 0011 1001 0110
union floatint c;
c.f=a.f b.f;
printf("0x%xn",c.i);
// gives 0x76935659 = 0111 0110 1001 0011 0101 0110 0101 1001=0 11101101 00100110101011001011001
}