The problem is that the input value is negative, and the javadoc for Long.toHexString() states "Returns a string representation of the long argument as an unsigned integer in base 16. The unsigned long value is the argument plus 2^64 if the argument is negative; otherwise, it is equal to the argument." However parseLong states "Parses the string argument as a signed long in the radix..."
So when you have a negative input, that 2^64 causes the NumberFormatException.
If the input is changed to
double doubleInput = 9.156013e-002;
the conversion works correctly without an exception. To deal with a negative input, a little additional processing is needed.
Here is a class that shows one way to do the conversion without using BigInteger or byte buffers:
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 a 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);
}
}