如何将小数部分转换为十六进制分数?

时间:2013-12-18 06:19:40

标签: language-agnostic hex decimal

所以我在想,你如何将小数部分转换为十六进制分数? 什么是转换的方法,还有捷径吗?

2 个答案:

答案 0 :(得分:21)

您可以使用此算法:

  1. 取一个小数部分(即整数部分等于零)
  2. 乘以 16
  3. 将整数部分转换为十六进制并将其放下
  4. 转到第1步
  5. 例如,让我们找出 pi = 3.141592653589793 的十六进制表示...

    整数部分很明显 - 0x3 ;至于小数部分( 0.141592653589793 )我们有

      0.14159265358979 * 16 =  2.26548245743664; int part  2 (0x2); frac 0.26548245743664
      0.26548245743664 * 16 =  4.24771931898624; int part  4 (0x4); frac 0.24771931898624
      0.24771931898624 * 16 =  3.96350910377984; int part  3 (0x3); frac 0.96350910377984
      0.96350910377984 * 16 = 15.41614566047744; int part 15 (0xF); frac 0.41614566047744
      0.41614566047744 * 16 =  6.65833056763904; int part  6 (0x6); frac 0.65833056763904
      0.65833056763904 * 16 = 10.53328908222464; int part 10 (0xA); ...
    

    所以 pi(十六进制)= 3.243F6A ...

    可能的(C#)实施

    public static String ToHex(Double value) {
      StringBuilder Sb = new StringBuilder();
    
      if (value < 0) {
        Sb.Append('-');
    
        value = -value;
      }
    
      // I'm sure you know how to convert decimal integer to its hexadecimal representation
      BigInteger bi = (BigInteger) value;
      Sb.Append(bi.ToString("X"));
    
      value = value - (Double)bi;
    
      // We have integer value in fact (e.g. 5.0)
      if (value == 0)
        return Sb.ToString();
    
      Sb.Append('.');
    
      // Double is 8 byte and so has at most 16 hexadecimal values
      for (int i = 0; i < 16; ++i) {
        value = value * 16;
        int digit = (int) value;
    
        Sb.Append(digit.ToString("X"));
    
        value = value - digit;
    
        if (value == 0)
          break;
      }
    
      return Sb.ToString();
    }
    

    测试

       Console.Write(ToHex(Math.PI)); // <- returns "3.243F6A8885A3"
    

答案 1 :(得分:0)

您可以通过将输入数乘以整数十六进制数来获得小数部分。然后,您可以使用常规的整数到十六进制转换。例如,要在(hexa)小数点后得到6个字符,请将小数部分乘以0x1000000。

以下是一些可以执行此操作的Java代码。

String toHexFraction(double x, int digits) {
    // Get fractional part.
    if (x < 0.0)
        x = 0.0 - x;
    x = x % 1.0;

    // Shift left by n digits
    long multiplier = (1L << (digits * 4));
    long fraction = (long)(x * multiplier);

    // Convert integer to hex string.
    // String should have at least n digits; prefix with zeros if not.
    String hex = Long.toHexString(fraction);
    String padding = "000000000000000";
    hex = padding.substring(0, digits - hex.length()) + hex;

    return hex;
}

String toHexInteger(double x) {
    long whole = (long) x;
    String prefix;
    if (whole < 0) {
        // Long.toHexString treats the number as an unsigned integer.
        whole = 0 - whole;
        prefix = "-";
    } else {
        prefix = "";
    }
    return Long.toHexString(whole);
}

String toHex (double x, int digits) {
    return toHexInteger(x) + "." + toHexFraction(x, digits);
}

位数将受到双精度表示的最大整数的限制。

这也适用于其他方形基地,例如:对于八进制更改digits * 4digits * 3,并使用Long.toOctalString