java 双到十六进制字符串和返回
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/5433807/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Double to Hex String and Back
提问by Andy
It's fairly simple to convert a double to a hexadecimal string in Java. But how do I do the reverse? My code is below and I've noted where a NumberFormatException
is thrown (about 2/3rds down).
在 Java 中将 double 转换为十六进制字符串相当简单。但我如何做相反的事情?我的代码在下面,我已经注意到 aNumberFormatException
被抛出的地方(大约 2/3 向下)。
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 );
}
}
Using Double.valueOf
fails in the same manner.
以Double.valueOf
同样的方式使用失败。
Edit: I've done a few searches on the web already and found some very inelegant solutions. For example: Using a BigInteger
seems like overkill. There's got to be a better way!
编辑:我已经在网上进行了一些搜索,发现了一些非常不雅的解决方案。例如:使用 aBigInteger
似乎有点矫枉过正。必须有更好的方法!
采纳答案by Peter Lawrey
You can break the String into two halves and parse each one, but I think this is the simplest.
您可以将 String 分成两半并解析每一半,但我认为这是最简单的。
long doubleAsLongReverse = new BigInteger(doubleAsString, 16).longValue();
In Java 8, there is now a
在 Java 8 中,现在有一个
long l = Long.parseUnsignedLong(doubleAsString, 16);
and to reverse this
并扭转这一局面
String s = Long.toUnsignedString(l, 16);
These can be used in combination with the methods converting raw double
to long
etc.
这些可以与将 raw 转换double
为long
等的方法结合使用。
回答by posdef
Why not use the methods provided in standard library: Double.valueOfand Double.toHexString
为什么不使用标准库中提供的方法: Double.valueOf和Double.toHexString
So a full round trip example would be
所以一个完整的往返示例将是
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
will give a boxed Double
and Double.parseDouble
will give a primitive double
choose as appropriate.
NbDouble.valueOf
会给出一个盒装的,Double
并Double.parseDouble
会给出一个double
适当的原始选择。
or am I misunderstanding something?
还是我误解了什么?
回答by muki61
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..."
问题是输入值为负,Long.toHexString()的 javadoc声明“以16 进制无符号整数形式返回 long 参数的字符串表示形式。无符号 long 值是参数加上 2^64,如果论点是否定的;否则,它等于论点。” 然而 parseLong 声明“将字符串参数解析为基数中的有符号长......”
So when you have a negative input, that 2^64 causes the NumberFormatException.
因此,当您输入负数时,2^64 会导致 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:
这是一个类,它显示了一种不使用 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);
}
}
And here is a junit test class:
这是一个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);
}
}
回答by ShelS
Example function to reverse 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();
}