Double hexadecimal string and vice versa

Just convert a double to a hexadecimal string in Java. But how can I do the opposite? My code is below and I noticed where it is being called NumberFormatException(about 2 / 3rds down).

public class HexToDoubleTest {
    public static void main( String args[] ) {

        // This is the starting double value
        double doubleInput = -9.156013e-002;

        // Convert the starting value to the equivalent value in a long
        long doubleAsLong = Double.doubleToRawLongBits( doubleInput );

        // Convert the long to a String
        String doubleAsString = Long.toHexString( doubleAsLong );

        // Print the String
        System.out.println( doubleAsString );

        // Attempt to parse the string back as a long
        // !!! This fails with a NumberFormatException !!!
        long doubleAsLongReverse = Long.parseLong( doubleAsString, 16 );

        // Convert the long back into the original double
        double doubleOutput = Double.longBitsToDouble( doubleAsLongReverse );

        // Confirm that the values match
        assert( doubleInput == doubleOutput );

    }
}

Use is Double.valueOfnot performed in the same way.

Edit: I have already done several searches on the Internet and found some very inelegant solutions. For example: Use BigIntegerseems redundant. There must be a better way!

+7
source share
4 answers

You can split the string into two halves and parse each, but I think this is the simplest.

long doubleAsLongReverse = new BigInteger(doubleAsString, 16).longValue();

In Java 8 there is now

long l = Long.parseUnsignedLong(doubleAsString, 16);

and completely change that

String s = Long.toUnsignedString(l, 16);
+2

, : Double.valueOf Double.toHexString

,

public static void main(String[] args){

    double doubleValue = -0.03454568;
    System.out.println("Initial double value is " + doubleValue);

    String hexStringRepresentation = Double.toHexString(doubleValue);
    System.out.println("Hex value is " + hexStringRepresentation);

    double roundtrippedDoubleValue = Double.valueOf(hexStringRepresentation);
    System.out.println("Round tripped double value is " + roundtrippedDoubleValue);
}

Nb Double.valueOf Double Double.parseDouble double .

?

+9

, , javadoc Long.toHexString() : " 16. 2 ^ 64, , ." parseLong : " long ..."

So, if you have negative input, then 2 ^ 64 throws a NumberFormatException.

If the input is changed to

double doubleInput = 9.156013e-002;

the conversion works correctly without exception. To deal with negative input, a little extra processing is required.

Here is a class that shows one way to do the conversion without using BigInteger buffers or bytes:

public class Temp {
  public String getDoubleAsHexString(double input) {
    // Convert the starting value to the equivalent value in a long
    long doubleAsLong = Double.doubleToRawLongBits(input);
    // and then convert the long to a hex string
    return Long.toHexString(doubleAsLong);
  }

  public double convertHexStrToDouble(String input) {
    // convert the input to positive, as needed
    String s2 = preprocess(input);
    boolean negative = true;
    // if the original equals the new string, then it is not negative
    if (input.equalsIgnoreCase(s2))
      negative = false;

    // convert the hex string to long
    long doubleAsLongReverse = Long.parseLong(s2, 16);

    // Convert the long back into the original double
    double doubleOutput = Double.longBitsToDouble(doubleAsLongReverse);

    // return as a negative value, as needed
    if (negative)
      return -doubleOutput;

    return doubleOutput;
  }

  private String preprocess(String doubleAsHexString) {
    // get the first char and convert it to an int
    String s0 = doubleAsHexString.substring(0, 1);
    int int1 = Integer.parseInt(s0, 16);

    // if the int is < 8, then the string is not negative
    // and is returned without further processing
    if (int1 < 8)
      return doubleAsHexString;

    // otherwise subtract 8
    int1 = int1 - 8;
    s0 = Integer.toString(int1);

    // don't prepend a "0"
    if (int1 == 0)
      s0 = "";

    // return the string with a new inital char
    return s0 + doubleAsHexString.substring(1);
  }
}

And here is the junit test class:

public class TempTest {
  private Temp t;

  @Before
  public void setUp() throws Exception {
    t = new Temp();
  }

  @Test
  public void testConvertHexStrToNegativeDouble() {
      double doubleInput = -9.156013e-002;
      String hexStr = t.getDoubleAsHexString(doubleInput);
      double doubleOutput = t.convertHexStrToDouble(hexStr);
      assertEquals(doubleInput, doubleOutput, 0.0);
    }

  @Test
  public void testConvertHexStrToPositiveDouble() {
    double doubleInput = 9.156013e-002;
    String hexStr = t.getDoubleAsHexString(doubleInput);
    double doubleOutput = t.convertHexStrToDouble(hexStr);
    assertEquals(doubleInput, doubleOutput, 0.0);
  }
}
+2
source

Example function for inverse double value:

public Double ReverseDouble( Double d) {

   byte[] bytes = new byte[8]; 
   ByteBuffer.wrap( bytes).putDouble( d); 

   for (int i=0;i<bytes.length/2;i++) {
       byte b = bytes[ i];
       bytes[ i] = bytes[ bytes.length -i -1];
       bytes[ bytes.length -i -1] = b;
   }

   return ByteBuffer.wrap( bytes).getDouble();
}
0
source