2015-03-01 2 views
6

Я пытаюсь преобразовать int в пользовательский float, в котором пользователь указывает количество бит, зарезервированное для exp и mantissa, но я не понимаю, как работает преобразование. Моя функция принимает значение int и int exp для представления числа (значение * 2^exp) i.e значение = 12, exp = 4, возвращает 192. но я не понимаю, какой процесс мне нужно сделать, чтобы изменить их. Я смотрел на это целыми днями и играю с веб-приложениями конвертера IEEE, но я просто не понимаю, что такое процесс нормализации. Как я вижу, его «переместить двоичную точку и настроить экспонента», но я не знаю, что это значит, может ли кто-нибудь дать мне пример, чтобы уйти? Также я не понимаю, что такое предвзятость. Единственная информация, которую я имею, это то, что вы просто добавляете номер своему экспоненту, но я не понимаю, почему. Я искал Google для примера, я могу понять, но это просто не делает никакого смысла для меняКак нормализовать mantissa

+0

Это двоичный эквивалент 0,01 -> 1e-2 IOW: сдвиньте мантиссой вправо/влево и добавьте/вычтите счетчик экспоненте. – wildplasser

+1

Если значение равно 12, и мы имеем это двоичное значение, это '00001100'. Это нужно переместить, чтобы быть '11000000 x 2^-4', а затем мы забываем о самом левом бите (поскольку он« всегда »1) и просто говорят, что это« [1] 1000000 x 2^-4'. – U2EF1

+0

Можете ли вы пояснить, что вы подразумеваете под «Я не понимаю процесс, который мне нужно сделать, чтобы изменить это»? Вы имеете в виду, что вы не знаете, как их изменить, когда вы делаете добавление/умножение? – eigenchris

ответ

0

Для нормализации мантиссы вы поместите десятичную точку слева от крайней левой ненулевой цифры

например

представляют 10.11 основание 2 в форме нормализуют

= 0,1011 основание 2 * 2 во второй степени

основание двух потому, что вы работаете с двоичными числами и мощности анолита 2 потому что вы переехали t его десятичная точка оставлена ​​два раза. Напомним, что только 4 бита используются для mantizza

поэтому mantizza бы 1011

+1

Можете ли вы привести более конкретный пример того, как это делается в коде? Как я понимаю, 3.1416 в двоичном формате будет 11.00100100001111 ... так что мне нужно нормализовать его до1.100100100001111 ... x 2^1 Я получаю абстрактную часть, но я не понимаю, как реально реализовать это –

4

«Процесс нормализации» преобразует входные сигналы в диапазоне выбора.

binary32 ожидает, что значение (не мантисса) будет находиться в диапазоне 1.0 <= s < 2.0, если число не имеет показателя минимальности.

Пример:
value = 12, exp = 4 не такое же, как
value = 12/(2*2*2), exp = 4 + 3
value = 1.5, exp = 7

Поскольку мантисса всегда ведущая цифра 1 (если число не имеет минимальный показатель), нет необходимо сохранить его. И вместо того, чтобы хранить экспонента как 7, к нему добавляется смещение 127.

значение = 1,5 десятичное -> 1,1000 ... 000 бинарных -> 0.1000 ... 000 сохраненные двоичные (23 бита) во всех
ехр = 7 -> смещения ехр 7 + 127 - > 134 десятичных -> 10000110 двоичного

Двоичный образец хранится это конкатенация «знак», «мантисса с ведущим 1 битом подразумеваемых» и «смещение показателем»

0 10000110 1000...000 (1 + 8 + 23 = 32 bits) 

при смещенный показатель равен 0 - минимальное значение i mplied бит 0 и поэтому небольшие числа, такие как 0.0, могут храниться.

Если смещенный показатель равен 255 - максимальное значение, данные хранятся больше не представляют конечные числа, а «бесконечность» и «не-цифры».

Проверьте ссылки, ссылки на которые приведены для получения более подробной информации.

11

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

Например, если мы возьмем число 13.25, которое 1101.01 в двоичной системе, 1101 будет целая часть и 01 будет дробная часть.

Я мог бы представлять 13.25 как 1101.01*(2^0), но это не нормировано, поскольку целочисленная часть не является 1. Однако, мы позволили сдвинуть мантиссу на правую одну цифру, если увеличить показатель на 1:

1101.01*(2^0) 
= 110.101*(2^1) 
= 11.0101*(2^2) 
= 1.10101*(2^3) 

Это представление 1.10101*(2^3) нормированная форма 13.25.


Тем не менее, мы знаем, что нормализованные числа с плавающей точкой всегда будет в форме 1.fffffff * (2^exp)

Ради эффективности, мы не потрудились хранить 1 целую часть в самом двоичном представлении, мы просто притворимся, что это там. Поэтому, если бы мы предоставили ваш собственный поплавок 5 бит для мантиссы, мы бы знали, что бит 10100действительно будет стоять за 1.10100.

Вот пример со стандартной 23-битной мантиссы:

enter image description here


Что касается смещения показателя, давайте взглянем на стандартном формате 32-бит float, который разбивается на 3 части: 1 бит знака, 8 бит экспоненты и 23 бит мантиссы:

s eeeeeeee mmmmmmmmmmmmmmmmmmmmmmm 

экспонент 00000000 и 11111111 имеют специальные цели (например, представляющие Inf и NaN), поэтому с 8 знаменательными битами мы можем представить 254 разных показателя, например 2^1, до 2^254. Но что, если мы хотим представить 2^-3? Как мы получаем отрицательные показатели?

Формат исправляет эту проблему на , автоматически вычитая 127 из экспонента.Поэтому:

  • 0000 0001 будет 1 -127 = -126
  • 0010 1101 будет 45 -127 = -82
  • 0111 1111 будет 127-127 = 0
  • 1001 0010 будет 136-127 = 9

Это изменяет диапазон экспоненты от 2^1 ... 2^254 к 2^-126 ... 2^+127 поэтому мымогут представлять отрицательные показатели.

3

Tommy - chux и eigenchris вместе с остальными предоставили отличные ответы, но если я правильно посмотрю на ваши комментарии, вы все еще, похоже, боретесь с орехами и болтами «как я возьму это info, а затем использовать это при создании пользовательского представления с плавающей точкой, где пользователь указывает количество бит для экспонента? " Не чувствуйте себя плохо, это ясно, как грязь, в первый раз, когда вы проходите через это. Я думаю, я могу взять удар, чтобы разобрать его.

Вы знакомы с представлением IEEE754-Single-прецизионной с плавающей точкой:

IEEE-754 Single Precision Floating Point Representation of (13.25) 

    0 1 0 0 0 0 0 1 0 1 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
|- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -| 
|s|  exp  |     mantissa     | 

Что 1-bit sign-bit, 8-bit biased exponent (в 8-битном избыточном-127 нотации), а остальные 23-bit mantissa.

Когда вы разрешаете пользователю выбирать количество бит в экспоненте, вам нужно будет переделать обозначение экспонента для работы с новым выбранным пользователем лимитом.

Что изменится?

  • Будет ли это изменить sign-bit обращение - Нет.

  • Будет ли это изменить mantissa обращение - Нет (вы еще конвертировать мантиссу/мантиссу в формате «скрытый бит»).

Итак, единственное, что вам нужно сосредоточиться, это exponent handling.

Как вы подходите к этому? Напомним, что текущий 8-разрядный показатель находится в так называемой нотации (где 127 представляет наибольшее значение для бит 7, что позволяет сдерживать любое смещение и выражаться в пределах текущего предела 8-bit. Если ваш пользователь выбирает 6 бит как ? размер показателя, то, что вы должны будете предоставить подобный метод страховать у вас есть фиксированное число, чтобы представить свой новый избыток -. ## обозначения, которые будут работать в пределах пользователя

Возьмите предел 6-bit пользователя , тогда выбор для несмещенного значения экспоненты можно было бы попробовать как 31 (самые большие значения, которые могут быть представлены в 5-bits). К этому вы могли применить ту же логику (принимая пример 13.25 выше).Ваше двоичное представление для числа: 1101.01, на которое вы перемещаете десятичную цифру 3 positions to the left, чтобы получить 1.10101, что дает вам погрешность экспонента 3.

В вашем 6-bit exponent случае вы бы добавить 3 + 31 получить свой excess-31 notation для показателя: 100010, а затем положить мантиссы в формате «скрытый бит» (т.е. падение ведущего 1 из 1.10101 в результате вашего нового пользовательского Tommy Precision Представление:

IEEE-754 Tommy Precision Floating Point Representation of (13.25) 

    0 1 0 0 0 1 0 1 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
|- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -| 
|s| exp |     mantissa      | 

с 1-bit sign-bit, 6-bit biased exponent (в 6-бит избытка 31 обозначения), а остальные 25-bit mantissa.

Те же правила будут применяться к обращению р чтобы вернуть номер с плавающей запятой из вышеуказанной нотации. (только используя 31 вместо 127, чтобы вернуть смещение экспоненты)

Надеюсь, это поможет в некотором роде. Я не вижу многого другого, что вы можете сделать, если действительно позволите выбрать размер экспонента, выбранный пользователем. Помните, что стандарт IEEE-754 не был чем-то, о чем догадались, и много хороших рассуждений и компромиссов вошли в схему расписания 1-8-23 sign-exponent-mantissa. Тем не менее, я думаю, что ваше упражнение отлично справляется с необходимостью строго понимать стандарт.

Теперь полностью потеряно и не указано в этом обсуждении - какие последствия это имеет для диапазона чисел, который может быть представлен в этом Custom Precision Floating Point Representation. Я не смотрел на него, но основным ограничением, по-видимому, было бы сокращение MAX/MIN, которое можно было бы представить.

0

Чтобы ответить на комментарий, размещенный на «как сделать это в коде»: (при условии, что это IEEE с плавающей точкой)

A) Извлечение без знака «показателя» и «мантиссы» от IEEE поплавка.

я) exp = 0x7F800000 & yourFloatVar;

// это принимает бит b1 через b8 от поплавка. (B0 является подписанным бит, В9 и на это мантисса)

II) exp = exp >> 23; // сдвиг вправо так, этот показатель является правильным, ориентированным на

III) exp += 127; // добавить в смещении (127 для 32 только -битных)

IV) mantissa = 0x007FFFFF & yourFloatVar; // занимают последние 23 битов из поплавка

B) нормализующее

I)

while(true) 
{ 
    if(((mantissa & 0xC0000000) != 0x80000000) 
     &&((mantissa & 0xC0000000) != 0x40000000)) 
    { 
     mantissa = mantissa << 1; 
     exponent--; 
    } 
    else //AKA the float has been normalized 
    { 
     break; 
    } 
} 

, если ведущие 2 бита не являются «01» или «10» (это свойство дополнения 2 - условие нормализации), затем сдвиг над мантиссой и уменьшение показателя экспоненты.

Я хочу отметить, что это вовсе не самый эффективный алгоритм для этого; Я просто хотел сделать шаги понятными. Надеюсь, я ничего не пропустил!

Смежные вопросы