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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-30 11:06:58  来源:igfitidea点击:

Double to Hex String and Back

javastringdata-structureshex

提问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 NumberFormatExceptionis 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.valueOffails 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 BigIntegerseems 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 doubleto longetc.

这些可以与将 raw 转换doublelong等的方法结合使用。

回答by posdef

Why not use the methods provided in standard library: Double.valueOfand Double.toHexString

为什么不使用标准库中提供的方法: Double.valueOfDouble.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.valueOfwill give a boxed Doubleand Double.parseDoublewill give a primitive doublechoose as appropriate.

NbDouble.valueOf会给出一个盒装的,DoubleDouble.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();
}