#математика #числа_с_плавающей_точкой
Есть такое задание в книге Structured Computer Organization в Appendix B. Floating-point
numbers:
4. The following binary floating-point numbers consist of a sign bit, an excess
64, radix 2 exponent, and a 16-bit fraction. Normalize them.
a. 0 1000000 0001010100000001
b. 0 0111111 0000001111111111
c. 0 1000011 1000000000000000
Мое решение
Я понимаю это задание так:
У нас есть следующий формат: 1 бит знака, 7 бит экспоненты, со смещением 64 и 16-битная
мантисса.
Нам нужно нормализовать число 0 1000000 0001010100000001, представленное в этом формате.
Число называется нормализованным, если крайний левый бит его мантиссы — это 1. Значит
нам нужно сдвинуть все биты мантиссы влево на 3 бита. Если мы сдвигаем число влево
на три бита, значит умножаем его на 2³. Следовательно, чтобы число не изменилось, нам
нужно уменьшить экспоненту на 3.
Если исходное число (0 1000000 0001010100000001) в десятичный вид, то получим:
+ 2^(64 - 64) × (2^(-4) + 2^(-6) + 2^(-8) + 2^(-16)) = +1 × 0.0820465087890625 =
+0.0820465087890625
Если перевести это же число, нормализованное мной, (0 0111101 1010100000001000),
то получим:
+ 2^(61 - 64) × (2^(-1) + 2^(-3) + 2^(-5) + 2^(-13)) = +2^(-3) × 0.6563720703125
= 0.125 × 0.6563720703125 = +0.0820465087890625
Т. е. то же самое число.
Решение автора книги
Решения нашел здесь. Я так понимаю, это официальные ответы, представленные издательством.
4. To normalize, shift left 1 bit at a time, adding 1 to the exponent at each step,
until the leftmost bit of the fraction is 1. The results are
(a) 0 1000011 1010100000001000
(b) 0 1000101 1111111111000000
(c) 0 1000011 1000000000000000
The third one is already normalized.
Решение @avp
Из-за расхождения в моем ответе и ответе автора, решил попросить помощи в чате C, C++:
…я понимаю этот пример по другому. Задан знак 0 -- положительное, экспонента --
1000000 == 0x40 == 64 (т.е. с учетом смещения 64 это 0) и 16-разрядное целое 0x1501
== 5377.
Вот его и надо переводить в дробь
@eanmos вообще, ваш взгляд на задачу наверное более правильный (вычесть 3 из экспоненты).
В моей интерпретации сама формулировка задачи выглядит слишком вычурно. И ответ (ответов
в книге я не нашел) в моей интерпретации будет -- прибавить к экспоненте 12 (поскольку
5377 надо для перевода в дробь делить на 4096), что явно не совпадает с ответом о котором
вы спрашиваете.
— @avp
Так какой ответ правильный? Как правильно решить это задание?
Ответы
Ответ 1
Вместо того, чтобы дублировать ответ из комментариев, немного распишу, как было бы представлено в IEEE 754 (Double precision) вышеупомянутое число 0.0820465087890625 В двоичном представлении без какого-либо дополнительного кодирования это число выглядит так: 0.00010101000000012 Что соответсвует нормализованному виду 1.0101000000012 × 2-4 тип double содержит такие битовые поля 1 бит - Знак 11 бит - Порядок (со смещением 1023) 52 бита - Мантисса (дробная ee часть) Целая часть мантиссы не записывается в память, дело в том, что числа в IEEE 754 (почти) всегда записываются в нормализованном виде, а значит перед точкой подразумевается единица. Итого получаем: Знак: 02 Порядок: -4 + 1023 = 011111110112 Мантисса: 01010000000100000000000000000000000000000000000000002 Проверить это можно, например, в python import struct value = 0b0_01111111011_0101000000010000000000000000000000000000000000000000 print(struct.unpack('d', struct.pack('q', value))) # (0.0820465087890625,) Так что единственная отличие от вашего решения в том, что порядок на единицу меньше.
Комментариев нет:
Отправить комментарий