Подтвердить что ты не робот

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

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

   float a=5.2  with below Diagram

enter image description here

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

4b9b3361

Ответ 1

Как было сказано, 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

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

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

Ответ 2

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

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

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

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

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

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

0 10000001 01001100110011001100110    
S    E               M

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    
S    E               M

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

01100110 01100110 10100110 01000000
MMMMMMMM MMMMMMMM EMMMMMMM SEEEEEEE

Ответ 3

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

Ответ 4

Представление 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

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

0101.00110...

Ответ 5

Raw float 5.2:

01000000101001100110011001100110
^ sign bit

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

01100110011001101010011001000000
                        ^ sign bit

Ответ 6

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....

Ответ 7

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' не придет.

Ответ 9

Техника конверсии, размещенная первоначально на другом веб-сайте, показана излишне сложной (хотя она требует от нас правильного ответа). Для представления памяти 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

Ответ 11

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

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