80-bit floating point and subnormal numbers

I am trying to convert an extended precision 80-bit floating-point number (in buffer) to double. The buffer basically contains the contents of the x87 register.

This question helped me get started as I was not familiar with the IEEE standard. In any case, I'm struggling to find useful information about subnormal (or denormalized) numbers in 80-bit format. I know that unlike float32 or float64 it does not have a hidden bit in the mantissa (adding 1.0 is not implied), so one way to find out if the number is normalized is to check if the most significant bit is set in the mantissa. This leaves me with the following question :

From what wikipedia tells me, float32 and float64 point to an abnormal number with a (offset) exponent of 0 and a nonzero mantissa.

  • What does this tell me in 80 bit swimming?
  • Can 80-bit mantissa floats, 1.0 even have a non-zero indicator?
  • Alternatively, do 80-bit floats with a score of 0 even have mantis> = 1.0?

EDIT: I think the question comes down to the following:

Can I expect the FPU to sanitize the exponent and the highest mantissa bit in the x87 register?

If not, which number should convert the result? Should I ignore the exhibitor at all? Or is it qNaN?

EDIT:

I read the FPU section in Intel's Guide (Intel® 64 and IA-32 Architect Software Developer's Guide, Volume 1: Basic Architecture), which was less scary than what I was afraid of. As it turned out, the following values ​​are not defined:

  • exponent == 0 + the highest bit mantissa
  • exponent! = 0 + mantissa without the highest bit

He does not mention whether these meanings can appear in the wild, and if they are internally transformed. So I actually cleaned out Ollydbg and manually set the bit to the x87 registers. I created ST (0) to contain all the bits set in the exponent, and mantissa 0. Then I did the execution

FSTP QWORD [ESP] FLD QWORD [ESP] 

The value stored in [ESP] been converted to signal NaN. After FLD , ST(0) contained quiet NaN.

I think this answers my question. I made the J-16 SDiZ decision because it is the most direct solution (although it does not explicitly explain some of the finer details).

In any case, the case is settled. Thanks to everyone.

+7
source share
2 answers

Try SoftFloat , it has floatx80_to_float32 , floatx80_to_float64 and floatx80_to_float128 . Define your own format, act accordingly.

+3
source

The problem with finding information about the lower 80-bit numbers may be due to the fact that 8087 does not use any special denormalization for them. Found on the MSDN page on Type float (C) :

The values ​​listed in this table apply only to normalized floating point numbers; denormalized floating point numbers have a lower minimum value. Please note that the numbers stored in the 80x87 register are always presented in 80-bit normalized form; numbers can only be represented in denormalized form when stored in 32-bit or 64-bit floating point variables (variables of type float and type long).

Edit

The above may be true for how Microsoft uses FPU registers. Another source has been found that points to this:

FPU data types :

An 80x87 FPU typically saves values ​​in a normalized format. When the floating point number is normalized, the HO bit is always one. In 32 and 64-bit floating point formats, 80x87 do not actually save this bit, 80x87 always assumes that it is one. Therefore, 32 and 64 bit floating point numbers are always normalized. In the expanded precision of an 80-bit floating-point format, 80x87 does not assume that X.O. Mantissa bit - one, H.O. bit number appears as part of the bit string.

Normalized values ​​provide maximum accuracy for a given number of bits. However, there are a large number of unnormalized values ​​that we can represent with an 80-bit format. These values ​​are very close to zero and represent a set of values, mantissa X.O. the bit is not zero. 80x87 FPUs support a special form of 80 bits, known as denormalized values.

+3
source

All Articles