在Java中将double转换为十六进制字符串相当简单。但是我该怎么做呢?我的代码在下面,我已经注意到NumberFormatException
被抛出的位置(大约2 / 3rds)。
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 );
}
}
使用Double.valueOf
以同样的方式失败。
编辑:我已经在网上做了一些搜索,发现了一些非常不优雅的解决方案。例如:使用BigInteger
似乎有点矫枉过正。必须有更好的方法!
答案 0 :(得分:9)
为什么不使用标准库中提供的方法: 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
choose as appropriate。
答案 1 :(得分:2)
你可以将String分成两半并解析每一个,但我认为这是最简单的。
long doubleAsLongReverse = new BigInteger(doubleAsString, 16).longValue();
在Java 8中,现在有一个
long l = Long.parseUnsignedLong(doubleAsString, 16);
并扭转这个
String s = Long.toUnsignedString(l, 16);
这些可以与将原始double
转换为long
等的方法结合使用。
答案 2 :(得分:2)
问题是输入值是负数,Long.toHexString()状态的javadoc“返回long参数的字符串表示形式,作为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);
}
}
答案 3 :(得分:0)
反转双值的示例函数:
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();
}
答案 4 :(得分:0)
将HexString转换为Long。
public long ConvertHexToLong(String hexValue){
return new BigInteger(hexValue, 16).longValue();
}