Estoy tratando de convertir un número de coma flotante de precisión extendida de 80 bits (en un buffer) en el doble. El buffer contiene básicamente el contenido de un registro x87.Números de coma flotante y subnormales de 80 bits
This question me ayudó a empezar porque no estaba tan familiarizado con el estándar IEEE. De todos modos, estoy luchando para encontrar información útil sobre números subnormales (o desnormalizados) en el formato de 80 bits. Lo que sé es que a diferencia de float32 o float64 no tiene un bit oculto en la mantisa (no hay una adición implícita de 1.0), así que una forma de saber si un número está normalizado es comprobar si el bit más alto en la mantisa es conjunto. Eso me deja con la siguiente pregunta:
Por lo que wikipedia me dice, float32 y float64 indican un número subnormal con un exponente (sesgado) de 0 y una mantisa distinta de cero.
- ¿Qué me dice eso en un flotador de 80 bits?
- ¿Pueden los flotadores de 80 bits con mantisa < 1.0 incluso tener un exponente distinto de cero?
- Alternativamente, ¿pueden los flotadores de 80 bits con un exponente de 0 incluso tener una mantisa> = 1.0?
EDIT: Creo que la cuestión se reduce a:
¿Puedo esperar que el FPU para desinfectar exponente y mantisa poco más alta en los registros x87?
En caso negativo, ¿qué tipo de número debería dar la conversión? ¿Debería ignorar el exponente por completo en ese caso? O es qNaN?
EDIT:
leí la sección FPU en el manual de Intel (Intel® 64 e IA-32 Arquitecturas de Software Manual del desarrollador, volumen 1: Arquitectura básica) que era menos miedo de lo que había temido . Pues resulta que los siguientes valores no están definidos:
- exponente == 0 + mantisa con el bit más alto establecido
- exponente = 0 + mantisa sin el conjunto de bits más alta
Doesn! Mencione si estos valores pueden aparecer en la naturaleza, ni si se convierten internamente. Por lo tanto, desempolvé Ollydbg y configuré bits manualmente en los registros x87. I hacen a mano ST (0) para contener todos los bits establecidos en el exponente y una mantisa de 0. Entonces lo hice ejecutar
FSTP QWORD [ESP]
FLD QWORD [ESP]
El valor almacenado en [ESP]
se convirtió en una señalización NaN. Después del FLD
, ST(0)
contenía un NaN silencioso.
Supongo que eso responde mi pregunta. Acepté la solución J-16 SDiZ porque es la solución más directa (aunque no explica explícitamente algunos de los detalles más finos).
De todos modos, caso resuelto. Gracias a todos.
¿No tiene a mano una unidad 8087 para hacer el trabajo? –
Probablemente va a necesitar pedirle a alguien que conozca un ensamblador que lo vuelva a colocar en un colector asociado con una variable en particular. –
@David Heffernan: Sí, pero C++ (de ahí la etiqueta) no garantiza que el doble largo tenga 80 bits de tamaño. De hecho, VC++ define long double y double para tener el mismo tamaño (64 bits). El ensamblador en línea parece ser la única forma de obtener conversiones perfectas (hay código en la pregunta que he vinculado), pero prefiero usar C++ sin formato, especialmente porque no hay un ensamblador en línea en VC++ de 64 bits. – pezcode