javafloating-pointprecisionx87x86-emulation

x86 80-bit floating point type in Java


I want to emulate the x86 extended precision type and perform arithmetic operations and casts to other types in Java.

I could try to implement it using BigDecimal, but covering all the special cases around NaNs, infinity, and casts would probably a tedious task. I am aware of some libraries that provide other floating types with a higher precision than double, but I want to have the same precision as the x86 80-bit float.

Is there a Java library that provides such a floating point type? If not, can you provide other hints that would allow to implement such a data type with less effort than coming up with a custom BigDecimal solution?


Solution

  • An 80-bit value should be best held as combination of a long (for the mantissa) and an int for the exponent and sign. For many operations, it will probably be most practical to place the upper and lower halves of the long into separate "long" values, so the code for addition of two numbers with matching signs and exponents would probably be something like:

    long resultLo = (num1.mant & 0xFFFFFFFFL)+(num2.mant & 0xFFFFFFFFL);
    long resultHi = (num1.mant >>> 32)+(num2.mant >>> 32)+(resultLo >>> 32);
    result.exp = num1.exp; // Should match num2.exp
    if (resultHi > 0xFFFFFFFFL) {
      exponent++;
      resultHi = (resultHi + ((resultHi & 2)>>>1)) >>> 1; // Round the result
    }
    rest.mant = (resultHi << 32) + resultLo;
    

    A bit of a nuisance all around, but not completely unworkable. The key is to break numbers into pieces small enough that you can do all your math as type "long".

    BTW, note that if one of the numbers did not originally have the same exponent, it will be necessary to keep track of whether any bits "fell off the end" when shifting it left or right to match the exponent of the first number, so as to be able to properly round the result afterward.