双十六进制字符串和后面

时间:2011-03-25 14:30:08

标签: java string data-structures hex

在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似乎有点矫枉过正。必须有更好的方法!

5 个答案:

答案 0 :(得分:9)

为什么不使用标准库中提供的方法: Double.valueOfDouble.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();
     }