#математика #числа_с_плавающей_точкой
Есть такое задание в книге 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,) Так что единственная отличие от вашего решения в том, что порядок на единицу меньше.
Комментариев нет:
Отправить комментарий