Проблема в том, что входное значение является отрицательным, и javadoc для Long.toHexString () states "Возвращает строковое представление длинного аргумента в виде целого числа без знака в базе 16. Длинное значение без знакааргумент плюс 2 ^ 64, если аргумент отрицательный; в противном случае он равен аргументу. "Однако parseLong заявляет, что "анализирует строковый аргумент как длинную со знаком в основании ..."
Так что, если у вас отрицательный ввод, то 2 ^ 64 вызывает NumberFormatException.
Если входизменено на
double doubleInput = 9.156013e-002;
преобразование работает без исключений.Чтобы справиться с отрицательным входом, требуется небольшая дополнительная обработка.
Вот класс, который показывает один способ выполнить преобразование без использования BigInteger или байтовых буферов:
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);
}
}
И здесьэто тестовый класс Junit:
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);
}
}