преобразование из двоичного в основание 10 с использованием преобразования с плавающей запятой

Это моя первая публикация.

Итак, вот моя проблема, я не понимаю следующий пример.

Двоичное представление: 01000000011000000000000000000000

=+(1.11)base 2x 2^(128-127) ‹-все вопросы относятся к этой строке.

=+(1.11)base 2 x2^1

=+(11.1) base 2

=+(1x21+1x20+1x2-1)=(3.5) base 10

Вопросы: Откуда 128-127?
Почему 1.11?


person user1596067    schedule 13.08.2012    source источник


Ответы (4)


В формате с плавающей запятой одинарной точности смещение порядка равно 127. И конкретный битовый шаблон, который вы указали кодирует число с плавающей запятой со 128 (1000000) в качестве показателя степени:

0 10000000 11000000000000000000000
s exponent fraction

Сначала посмотрите на бит знака (s), это 0. Итак, это положительное число.

Затем вы вычитаете смещение экспоненты из экспоненты, откуда берется 128 - 127. Это дает 1.

Затем мы начинаем складывать биты дроби вместе (11000000000000000000000):

1 + 0.5 + 0.25 + 0 + 0 + 0....

Дает 1,75

Теперь у нас есть 1 (знак) * 2 ^ 1 (показатель степени) * 1,75 (дробь) = 2 * 1,75 = 3,5.

Другой пример:

00111110101010101010101010101011

Сломай:

0 01111101 01010101010101010101011
s exponent fraction

Знак равен 0, так что это снова положительное число.

125 (01111101) показатель степени, вычесть из него смещение степени: 125 - 127 = -2

Расшифруйте дробь 01010101010101010101011

1 + 0 + 0.25 + 0 + 0.0625 + 0 + 0.015625 + 0 + 0.00390625 + 0 + 0.0009765625 + 0 + 0.000244140625 + 0 + 0.00006103515625 + 0 + 0.0000152587890625 + 0 + 0.000003814697265625 + 0 + 9.5367431640625e-7 + 0 + 2.384185791015625e-7 + 1.1920928955078125e-7

Это дает 1.3333333730697632 или около того.

Теперь складываем все вместе:

1(sign) * 2^-2(exponent) * 1.3333333730697632(fraction) = 0.25 * 1.3333333730697632 = 0.3333333432674408 =~ 0.3333333
person Esailija    schedule 13.08.2012
comment
Кстати, если вы не хотите выполнять декодирование дробей вручную, jsfiddle.net/jcnN7/1 - person Esailija; 13.08.2012

Прежде всего, самое первое, что вам нужно сделать, это разделить поля (с учетом 32-битной кодировки с плавающей запятой IEEE 754):

Бит знака: 0

Биты экспоненты: 10000000

Биты мантиссы: 11000000000000000000000

(128 - 127) вычисляет показатель степени путем вычитания смещения степени.

При преобразовании из числа с плавающей запятой в десятичное число вычитается смещение экспоненты. При преобразовании в другую сторону вы добавляете его. Смещение экспоненты рассчитывается как:

2^(k−1) − 1, где k — количество битов в поле экспоненты.

2^(8 - 1) - 1 = 127

Мантисса равна 1,11 по основанию 2 (двоичному). Мантисса состоит из дроби и имеет подразумеваемую ведущую единицу. Следовательно, с 11000... в битах мантиссы у вас есть подразумеваемая ведущая единица, которая дает вам 1,11.

Если бы биты мантиссы были 1011, ваше значение дроби было бы 1,011.

person Chris Dargis    schedule 13.08.2012

Этот учебник должен помочь вам лучше понять плавающие точки:

http://www.tfinley.net/notes/cps104/floating.html

Двоичное представление разбито на 3 части: 1 бит знака, 8 бит экспоненты и 23 бита мантиссы.

   0|10000000|11000000000000000000000
sign|exponent|       mantissa

Знаковый бит равен нулю, что означает, что это положительное число. Показатель степени (128), который по определению на 127 больше фактического значения, разрешается в 1 (т.е. 128 - 127). Мантисса равна 1,11 (подразумевается ведущая 1, опять же по определению). Таким образом, мы имеем

  01000000011000000000000000000000
= +(1.11)base 2 x 2^(128-127)
= (2^0 + 2^-1 + 2^-2) x 2^1
= 2^1 + 2^0 + 2^-1
= 2 + 1 + 0.5
= 3.5
person Andrew    schedule 13.08.2012

Я думаю, что причина смещения (+127) в показателе степени заключается в следующем:

если вы интерпретируете число с плавающей запятой как 32-битное целое число, то вы не меняете порядок.
То есть

float a,b;
assert((a < b) == ((int)(a) < (int)(b)));
  • следовательно, сначала идет бит знака, затем показатель степени, затем мантисса
  • следовательно, наименьший положительный поплавок имеет нулевой показатель
  • следовательно, 0.0 кодируется со всеми битами, установленными в 0

Таким образом, вам нужно устранить смещение показателя степени, вычитая 127...

РЕДАКТИРОВАТЬ: неравенство работает для обычного числа с плавающей запятой, но не для NaN

person aka.nice    schedule 14.08.2012