Is there a Java equivalent of frexp?

c, c++, floating-point, java, math.h

Solution

How's this?

public static class FRexpResult
{
   public int exponent = 0;
   public double mantissa = 0.;
}

public static FRexpResult frexp(double value)
{
   final FRexpResult result = new FRexpResult();
   long bits = Double.doubleToLongBits(value);
   double realMant = 1.;

   // Test for NaN, infinity, and zero.
   if (Double.isNaN(value) || 
       value + value == value || 
       Double.isInfinite(value))
   {
      result.exponent = 0;
      result.mantissa = value;
   }
   else
   {

      boolean neg = (bits < 0);
      int exponent = (int)((bits >> 52) & 0x7ffL);
      long mantissa = bits & 0xfffffffffffffL;

      if(exponent == 0)
      {
         exponent++;
      }
      else
      {
         mantissa = mantissa | (1L<<52);
      }

      // bias the exponent - actually biased by 1023.
      // we are treating the mantissa as m.0 instead of 0.m
      //  so subtract another 52.
      exponent -= 1075;
      realMant = mantissa;

      // normalize
      while(realMant > 1.0) 
      {
         mantissa >>= 1;
         realMant /= 2.;
         exponent++;
      }

      if(neg)
      {
         realMant = realMant * -1;
      }

      result.exponent = exponent;
      result.mantissa = realMant;
   }
   return result;
}

This is "inspired" or actually nearly copied identically from an answer to a similar C# question. It works with the bits and then makes the mantissa a number between 1.0 and 0.0.

Problem

Is there a Java equivalent of the C / C++ function called frexp? If you aren't familiar, frexp is defined by Wikipedia to "break floating-point number down into mantissa and exponent." I am looking for an implementation with both speed and accuracy but I would rather have the accuracy if I could only choose one. This is the code sample from the first reference. It should make the frexp contract a little more clear: ``` /* frexp example */ #include <stdio.h> #include <math.h> int main () { double param, result; int n; param = 8.0; result = frexp (param , &n); printf ("%lf * 2^%d = %f\n", result, n, param); return 0; } /* Will produce: 0.500000 * 2^4 = 8.000000 */ ```

Original source

Related problems