Confusión con el cálculo de la mantisa de un punto flotante a partir de un número binario

2

Uso este convertidor para convertir un Número binario de 32 bits a un número de punto flotante. Primero encuentro el hexadecimal del número binario de 32 bits y lo convierto a decimal usando el convertidor.

En mi caso, el número binario de 32 bits es: 11001010110010001101011010011001

Esto es CAC8D699 en hexadecimal.

A continuación se muestra este ejemplo de conversión:

El resultado es -6581068.5.

Puedo entender cómo se calculan el signo y el exponente. Pero traté de aprender cómo se calcula la mantisa y no pude encontrar una explicación clara.

¿Cómo se convierte la sección de mantisa de 23 bits, es decir, 00110001110001110111000 convertida a 1.5690490 en este caso?

    
pregunta Genzo

1 respuesta

2

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.

    
respondido por el Harry Svensson

Lea otras preguntas en las etiquetas