Как представить номер FLOAT в памяти на C

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

float a=5.2 with below Diagram 

введите описание изображения здесь

Может ли кто-нибудь рассказать, как этот 5.2 преобразован в двоичный и как он представлен в памяти выше приведенной выше диаграммы?

Как было сказано, 5.2 представляется в виде знакового бита, показателя степени и мантиссы. Как вы кодируете 5.2?

5 легко:

 101. 

Остальное 0.2 – 1/5, поэтому разделите 1.00000... (hex) на 5, и вы получите 0.3333333... (hex).

(Это можно сделать более легко, если вы считаете один бит меньше: 0.FFFF...F / 5 = 3 , поэтому легко увидеть, что 0.FFFF... / 5 = 0.33333... недостающий бит не имеет значения при делении на 5, поэтому 1.0000... / 5 = 0.3333... тоже).

Это должно дать вам

 0.0011001100110011001100110011... 

Добавьте 5, и вы получите

 101.00110011001100110011... exp 0 (== 5.2 * 2^0) 

Теперь сдвиньте его вправо (нормализуйте его, т. Е. Убедитесь, что верхний бит находится непосредственно перед десятичной точкой) и соответствующим образом настройте экспоненту:

 1.010011001100110011001100110011... exp +2 (== 1.3 * 2^2 == 5.2) 

Теперь вам нужно только добавить смещение 127 (т.е. 129 = 0b10000001 ) к экспоненте и сохранить его:

 0 10000001 1010 0110 0110 0110 0110 0110 

Забудьте верхнюю часть мантиссы (которая всегда должна быть 1, за исключением некоторых специальных значений, поэтому она не сохраняется), и вы получаете:

 01000000 10100110 01100110 01100110 

Теперь вам нужно только решить маленький или большой конец.

Это не совсем так, как это работает, но это более или менее то, что происходит, когда число, подобное 5.2, преобразуется в двоичный.

Я думаю, что диаграмма не соответствует одному правилу.

Поплавки хранятся в памяти следующим образом:

Они разлагаются на:

  • знак s (обозначая, является ли он положительным или отрицательным) – 1 бит
  • mantissa m (по существу цифры вашего номера – 24 бит
  • показатель e – 7 бит

Тогда вы можете написать любое число x как s * m * 2^e где ^ обозначает возведение в степень.

5.2 следует представлять следующим образом:

 0 10000001 01001100110011001100110 SEM 

S=0 означает, что это положительное число, т. Е. s=+1

E следует понимать как беззнаковое число, представляя 129 . Обратите внимание, что вы должны вычесть 127 из E чтобы получить исходный показатель e = E - 127 = 2

M следует интерпретировать следующим образом: оно интерпретируется как число, начинающееся с символа 1 за которым следует точка ( . ), А затем цифры после этой точки. Цифры после . которые фактически закодированы в m . Введем веса для каждой цифры:

 bits in M: 0 1 0 0 1 ... weight: 0.5 0.25 0.125 0.0625 0.03125 ... (take the half of the previous in each step) 

Теперь вы суммируете весы, где установлены соответствующие биты. После того, как вы это сделали, вы добавите 1 (из-за нормализации в стандарте IEEE вы всегда добавляете 1 для интерпретации M ) и получаете оригинал m .

Теперь вы вычисляете x = s * m * 2^e и получаете свой исходный номер.

Итак, остается только, что в реальной памяти байты могут быть в обратном порядке. Вот почему номер не может быть сохранен следующим образом:

 0 10000001 01001100110011001100110 SEM 

но больше наоборот (просто возьмите 8-битные блоки и зеркалируйте их порядок)

 01100110 01100110 10100110 01000000 MMMMMMMM MMMMMMMM EMMMMMMM SEEEEEEE 

Значение представлено в памяти в обратном порядке, но путаница может состоять в том, что 5.2f действительно представляется как 5.1999998 из-за потери точности значений с плавающей запятой.

Представление 5.2 очень просто в двоичной логике:

  8 4 2 1 5 -> 0 1 0 1 

Для десятичного числа:

Возьмите .2 и умножьте на 2 (так как он представлен в двоичном виде).

 .2 X 2 = 0.4 -> take the value after the decimal point, don't take the value before the decimal point .4 X 2 = 0.8 .8 X 2 = 1.6 .6 X 2 = 1.2 .2 X 2 = 0.4 

и так далее…

После этого шага выведите значение перед десятичной точкой из вывода вышеописанных шагов:

 .2 X 2 = 0.4 -> take 0 from this for representing in binary form 

Таким образом, окончательный вариант 5.2:

 0101.00110... 

Сырье поплавок 5.2:

 01000000101001100110011001100110 ^ sign bit 

В памяти, порядок обратного байта (как ваша диаграмма):

 01100110011001101010011001000000 ^ sign bit 

5,2

Число хранится в форме «Знак бит», «Экспонента», «Мантисса». В двоичной форме 5 это 8 4 2 1 поэтому 0101 и .2 равно

 .2*2=.4 0 .4*2=.8 0 .8*2=1.6 1 

и знак бит 0 Потому что число положительно.

 0 0101 001.... 

5.2 в двоичном выражении 101.00110011 …… ——> не нормированная форма 5.2 равна .10100110011 …. x 2 ^ 3 ——> явная нормальная форма 5.2 равна .0100110011 x 2 ^ 3 в неявной нормальной форме

здесь знак бит становится 0 (потому что число положительное), а показатель – семь бит, поэтому он использует избыточную 64 экспоненциальную нотацию, поэтому показатель будет равен 64 + 3 = 69, то есть 1000101, а оставшимся будет мантисса (всего 32 бит – 7 экспоненциальных бит – 1 знаковый бит = 24 бит) 0100 1100 1100 1100 1100 1100

В приведенном выше примере бит знака правильный. Excess 64 не применяется, поэтому не нормализуется, но в идеале он должен использовать неявную нормировку Mantissa во втором байте, если вы применяете неявную нормализацию MSB ‘1’ не будет.

5.2 представлен как «01000000101001100110011001100110»

Проверьте апплет конвертера

Техника конверсии, размещенная первоначально на другом веб-сайте, показана излишне сложной (хотя она требует от нас правильного ответа). Для представления памяти 5.2 в памяти:

Сначала преобразуйте его в простую двоичную систему, которая даст нам 101.001100110011001100110011

Теперь измените его на научную форму: 1.01001100110011001100110011 x 10 ^ 2.

Теперь наш знаковый бит равен 0, так как число положительно

Для экспоненты нам нужно (127 + 2) до 8 бит, что дает нам 10000001

Фракция – 01001100110011001100110. (23 бит) (Отбрасывание ведущей 1 научной формы)

=> представление

0 10000001 0100 1100 1100 1100 1100 110

Ниже двух ссылок действительно помогло мне понять кодировку чисел с плавающей точкой IEE 754 в двоичном формате,

http://www.pitt.edu/~juy9/142/slides/L3-FP_Representation.pdf

http://en.wikipedia.org/wiki/Single-precision_floating-point_format

 int a; float b=5.2; memcpy(&a, &b, 4); printf("%d",a); 

Это дает 0100 0000 1010 0110 0110 0110 1000 0001 (1084647041)

  • void main () {if (sizeof (int)> -1) printf ("true"); else printf ("false"); ;
  • Как преобразовать строку в float?
  • Как работает getchar ()?
  • Объявление функции C для возврата массива
  • Является ли пустой список инициализаций допустимым кодом C?
  • возвращая несколько значений из функции
  • Как получить список каталогов в C?
  • О примерном определении
  • локальная переменная, инициализированная нулем в C
  • используя rand для генерации случайных чисел
  • C - передача массива 2d в качестве аргумента функции?
  • Давайте будем гением компьютера.