Convertir BCD a IEEE-754

0

Estoy tratando de convertir un número que obtengo de un teclado al estándar IEEE-753 usando VHDL o una implementación lógica, no quiero una respuesta completa, solo una guía sobre cómo debería fomentar esto.

Leí un teclado y almacené en la memoria cada dígito de la parte entera y la parte decimal, y el usuario también tiene la opción de ingresar el exponente que también se guarda en otra posición de memoria.

Leí en este sitio web sobre cómo convertir un número decimal al estándar IEEE. Supongamos ahora que tengo un número representado en notación científica, por ejemplo:

  

22.523 x 10 ^ 20

Leí este número en BCD de mi memoria, así que necesito convertirlo a binario para procesarlo, mi idea es:

  1. Convierta toda la parte a binario.
  2. Tomar la parte entera binaria y multiplicarla por 10 veces indicada por el exponente en este caso, 22 x 10 ^ 20.
  3. Convierta la parte decimal a binario.
  4. Tomar parte decimal binaria y multiplicar por 10 veces indicada por el [exponente] - [número de dígitos decimales] en este caso, 523 x 10 ^ 17.
  5. Agrega los dos números binarios.

Ahora tengo mi número en binario y puedo aplicar el método indicado en el sitio web.

Para representar este número necesitaré dos registros, uno para cada parte del número que necesitará el primero: log2(22 x 10^20) bits que es de 71 bits y la segunda parte necesitará log2(523 x 10^17) bits que es de 66 bits, así que necesitará 71 + 66 = 137 bits para almacenar el resultado y luego convertirlo a IEEE-753.

¿Esto es normal? ¿Hay alguna otra manera de hacerlo? ¿O se logra de esta manera?

    
pregunta Andres

2 respuestas

2

En primer lugar, esto no es algo que normalmente haría en hardware; haría esto en el firmware de un microprocesador, ya sea interno o externo al FPGA.

Pero si absolutamente tenía diseñar una ruta de datos para hacer esto, no debería requerir nada más que un sumador de números enteros y un multiplicador de números enteros, junto con un registro al que llamaremos "acumulador de números enteros" para maneje el exponente, y un sumador IEEE-754 y un multiplicador IEEE-754 junto con un registro acumulador IEEE-754 para manejar la mantisa y finalmente producir el resultado final.

Vamos a aclarar la terminología: en un número como 22.523 × 10 20 , el "22.523" es la mantisa y el "20" es el exponente. Llamémoslos "mantisa decimal" y "exponente decimal" para distinguirlos de la mantisa binaria y el exponente binario que eventualmente produciremos.

Comience por convertir el exponente decimal a binario, lo que requiere escanear sus dígitos de izquierda a derecha, multiplicando el entero acumulador por 10 antes de sumar el siguiente dígito. Niega el resultado si el exponente es negativo.

Ahora, comienza a convertir la mantisa decimal. Nuevamente, escaneando de izquierda a derecha, usamos una tabla de búsqueda para convertir cada dígito BCD a su equivalente IEEE-754. Tomamos el acumulador IEEE-754, lo multiplicamos por 10 y le agregamos el dígito convertido. Después de encontrar el punto decimal, continuamos convirtiendo los dígitos, pero ahora también disminuimos la versión binaria del exponente decimal que calculamos en el párrafo anterior una vez por cada dígito.

En este punto, tenemos una representación de enteros de la mantisa decimal en el acumulador IEEE-754, y tenemos una versión ajustada correctamente del exponente decimal original en el acumulador de enteros.

El último paso es mirar el acumulador de enteros. Si es positivo, entra en un bucle que multiplica el acumulador IEEE-754 por 10 (nuevamente, desde una tabla de búsqueda) y disminuye el acumulador de números enteros hasta que llega a cero. Si el acumulador de enteros es negativo, multiplique el acumulador IEEE-754 por 0.1 e incremente el acumulador de enteros hasta que sea cero. En cualquier caso, cuando termine, tendrá el número final de punto flotante en el acumulador IEEE-754.

Ah, y si la mantisa decimal es negativa, establezca el bit de signo en el número IEEE-754.

Hay muchas formas posibles de optimizar este proceso, pero eso dependería de su situación exacta. Espero que esto sea suficiente para ponerte en marcha.

    
respondido por el Dave Tweed
0

Necesitas mantener la mantisa y el exponente separados por el mayor tiempo posible.

22.523 = 22523 x 10 ^ -3, por lo que 22.523x10 ^ 20 es 22523x10 ^ 17.

Entonces, la conversión de la mantisa es muy parecida a cualquier conversión de enteros de base 10 a base 2, pero solo necesitas registrar cuando veas el punto decimal, y cuántos dígitos vienen después del punto decimal.

mantissa    = 0
in_fraction = false
denominator = 0
while (more input):
  if (no more mantissa (i.e. you see a non-digit)):
    break
  if (next_character is a "."):
    in_fraction = true
    continue
  mantissa = mantissa * 10 + next_digit
  if (in_fraction):
    denominator = denominator + 1

now read the exponent
exponent = exponent - denominator
now follow the rest of the algorithm (which is the really hard part)

La parte realmente difícil es que la mantisa es una fracción con algo de poder de 5s y 2s en el denominador. Cuando intentas aproximar con precisión la fracción con una fracción con solo una potencia de 2 denominadores, a veces tienes que hacer la división larga.

El documento clásico que mostró cómo lidiar con el redondeo de dividir por 5 es William D Clinger, "Cómo leer números de punto flotante con precisión", Proc ACM Conf on Prog Lang Dsgn and Impl , (PLDI): 92-101, 1990 . Si recuerdo bien, él da algunas optimizaciones que a veces te permiten escapar sin hacer la aritmética de muchos dígitos.

    
respondido por el Wandering Logic

Lea otras preguntas en las etiquetas