Чтобы закодировать плавающее число, мы должны переписать его как (-1) s 2 e 1.m и кодировать различные части в 32 бита следующим образом
![enter image description here](https://i.stack.imgur.com/ToXoH.png)
(из https://en.wikipedia.org/wiki/Single-precision_floating-point_format)
Первый бит - это знак s: 0 для + и 1 для -
8 следующих битов - это сдвинутый показатель степени e + 127
23, последние биты - дробная часть мантиссы (м)
Сложная задача - преобразовать мантиссу в двоичную. Для некоторых чисел это легко. Например, 5,75 = 4 + 1 + 1/2 + 1/4 = 2 2 + 2 0 + 2 -1 + 2 -2 = 101,11 = 1,0111 × 2 2
Для других чисел (как у вас) это сложнее. Решение состоит в том, чтобы умножить число на два, пока мы не найдем целое число или мы не превысим общее количество бит в коде (23 + 1).
Мыможет сделать это для вашего номера:
12.13 = 12.13 2^-0
= 24.26 2^-1
= 48.52 2^-2
= 97.04 2^-3
= 194.08 2^-4
= 388.16 2^-5
= 776.32 2^-6
= 1552.64 2^-7
= 3105.28 2^-8
= 6210.56 2^-9
= 12421.12 2^-10
= 24842.24 2^-11
= 49684.48 2^-12
= 99368.96 2^-13
= 198737.92 2^-14
= 397475.84 2^-15
= 794951.69 2^-16
= 1589903.38 2^-17
= 3179806.75 2^-18
= 6359613.50 2^-19
= 12719227.00 2^-20
Следующая итерация приведет к числу больше 2 ^ 24 (= ~ 16M), и мы можем остановиться.
MantiКод ssa легко (но немного длинен) конвертировать вручную в двоичный файл, используя обычные методы, и его код 0xc2147b.Если мы извлечем ведущий бит в 1 в позиции 2 23 и поместим его слева от «точки», мы получим мантиссу = 1.42147b × 2 23 (где дробная часть ограничена23 бита).Так как нам пришлось умножить на начальное число 2 20 , чтобы получить это значение, мы наконец получили
mant = 1.42147b × 2 3
Таким образом, показатель степени равен 3, а его код равен 3 + 127 = 130
exp = 130 d = 0x82
и так как число отрицательное
sign = 1
Нам осталось только подавить целую часть мантиссы (скрытый бит) и объединить эти числа, чтобы получить окончательное значение0xc142147b
(Конечно, я использовал программу для генерации этих чисел. Если интересно, вот код C)
#include <stdio.h>
int main () {
float f=-12.13;
int sign=(f<0.0);
float fmantissa;
fmantissa = (f<0.0?-f:f) ; // abs value of f
int e = 0 ; // the raw exponent
printf("%2.2f = %11.2f 2^-%d\n",f,fmantissa,e);
while (fmantissa<=(1<<23)){
e++; fmantissa*=2.0;
printf(" = %11.2f 2^-%d\n",fmantissa,e);
}
// convert to int
int mantissa=fmantissa;
//and suppress hidden bit in mantissa
mantissa &= ~(1<<23) ;
// coded exponent
int exp=127-e+23;
printf("sign: %d exponent: %d mantissa: 1.%x\n",sign, exp, mantissa);
//final code
int fltcode = (sign << 31) | (exp << 23) | mantissa;
printf("0x%x\n",fltcode);
}