Para que esta respuesta sea breve, responderé cómo funcionaría con un número de punto flotante de 8 bits y un número de punto fijo de 8 bits. Realmente no sé cómo se hace normalmente, por lo que así sería como lo haría si me dieran esta pregunta en un examen.
El número de punto flotante tendrá los siguientes bits:
\ $ [~ s ~ | ~ e_2 ~ | ~ e_1 ~ | ~ e_0 ~ | ~ f_3 ~ | ~ f_2 ~ | ~ f_1 ~ | ~ f_0 ~] \ $
donde:
- s = signo
- e = exponente \ $ - 3 \ $
- f = fracción (mantisa / significado)
Un breve ejemplo:
\ $ [~ 0 ~ | ~ 110 ~ | ~ 1001 ~] = + ~ | ~ 2 ^ {6-3} ~ | ~ 1.1001 = 1.5625 × 2 ^ 3 = 12.5 \ $
\ $ [~ 0 ~ | ~ 001 ~ | ~ 0011 ~] = + ~ | ~ 2 ^ {1-3} ~ | ~ 1.0011 = 1.1875 × 2 ^ {- 2} = 0.296875 \ $
\ $ [~ 1 ~ | ~ 100 ~ | ~ 1000 ~] = - ~ | ~ 2 ^ {4-3} ~ | ~ 1.1000 = -1.5 × 2 ^ {1} = - 3 \ $
\ $ [~ 1 ~ | ~ 000 ~ | ~ 0000 ~] = - ~ | ~ 2 ^ {0-3} ~ | ~ 1.0000 = -1 × 2 ^ {- 3} = - 0.125 \ $
El número de punto fijo tendrá los siguientes bits:
\ $ [~ s ~ | ~ d_3 ~ | ~ d_2 ~ | ~ d_1 ~ | ~ d_0 ~ | ~ d _ {- 1} ~ | ~ d _ {- 2} ~ | ~ d _ {- 3} ~] \ $
donde:
- s = \ $ - 16 \ $
- d = número \ $ × ~ 2 ^ {- 3} \ $
Un breve ejemplo:
\ $ [~ 0 ~ | ~ 0000001 ~] = 0 ~ | ~ + 0000.001 = 0.125 \ $
\ $ [~ 0 ~ | ~ 1111000 ~] = 0 ~ | ~ + 1111.000 = 15 \ $
\ $ [~ 1 ~ | ~ 0000001 ~] = - 16 ~ | ~ + 0000.001 = -14.875 \ $
\ $ [~ 1 ~ | ~ 1111000 ~] = - 16 ~ | ~ + 1111.000 = -1 \ $
En la computadora, 0.125 se almacenará como "00000001", pero su valor binario es 0000.001, así que no te confundas con el punto decimal. Todavía está en el mismo byte. 8 bits.
Así que vamos a convertir de formato fijo a flotar. Recuerda, este es el camino de Harry (ese soy yo).
Aquí hay algunas cosas importantes en las que centrarse:
- Los bits fraccionarios representan valores entre 0 y 1, luego se agrega 1 a esto. Así que la fracción resultante se encuentra entre 1 y 2.
- Una multiplicación por 2 es lo mismo que un desplazamiento a la izquierda por 1
- Una división por 2 es lo mismo que un desplazamiento a la derecha por 1
Así que aquí hay un pseudo código que se me ocurrió que debería convertirlo correctamente en valores positivos. Con pocas ediciones puede cubrir cero y números negativos también.
float8 fixed_to_float(fixed8 a){
float8 b; //float8 doesn't exist. It's my custom one, SEEEFFFF.
fixed8 e = 3;//fixed8 doesn't exist, but imagine a int8 where 16 means 1.
while(a>=2){
a>>=1;
//divide "a" by a factor two until
//it is less than 2
e++;
//count the number of right shifts
}
while(a<1){
a<<=1;
//multiply "a" by a factor two until
//it is greater than or equal to 1
e--;
//count the number of right shifts
}
}
a-=1;
//remove the "1" from 1.125 and keep the 0.125
e<<=4;
//move it into the right position for the floating point representation
b=e||a;
//logical OR e and a together.
return b;
}
Para que este código funcione, el tipo de datos "arreglado" tiene que ser personalizado con el "<" el operador 0000.1111 se registra como 0.9375 (15/16) que es menor que 1. O intenta hacer que el valor se encuentre entre 32 y 16 en lugar de 2 y 1.
Seudo código de fijo a flotante en acción:
a = \ $ 4.5 = 100.1 = [~ 0 ~ | ~ 100100 ~] \ $
e = \ $ 3 \ $
\ $ 100.100_2 \ $ es mayor o igual que \ $ 010.000_2 \ $, agregue 1 a e (e = \ $ 100_2 \ $)
\ $ 010.010_2 \ $ es mayor o igual que \ $ 010.000_2 \ $, agregue 1 a e (e = \ $ 101_2 \ $)
\ $ 001.001_2 \ $ es menor que \ $ 010.000_2 \ $, detener
a - = \ $ 1 = 00000010_2 \ $
e < < \ $ = 4 = 01010000_2 \ $
PS
a = ~ 00000010_2 \\
e = ~ 01010000_2 ~ O \\
\ overline {b = ~ 01010010_2}
\ $
Verificación:
\ $ [~ 0 ~ | ~ 101 ~ | ~ 0010 ~] = + ~ | ~ 2 ^ {5-3} ~ | ~ 1.0010 = 1.125 × 2 ^ 2 = 4.5 \ $
Me detendré aquí ya que la pregunta era cómo pasar del punto fijo al punto flotante. Pero técnicamente estoy mostrando cómo la conversión se realiza en la parte superior de esta respuesta con los ejemplos de punto flotante.