如何在 Java 中将 IEEE-754 二进制表示字符串转换为浮点型或双精度型?

Ḿűỻ*_*ṩ ᛗ 4 java string floating-point ieee-754 string-parsing

由于所有 Java 浮点数(即floatdouble)在内部都表示为位,因此我想找到一种有效的算法来转换表示该floatdouble的位的 String并将其转换为相应的浮点数-我找不到它的内置库函数,所以我只能自己编写它。

长度为 32 的二进制 String 表示float,而长度为 64 的二进制 String 将转换为double。所有浮点数都可以转换为双精度数,而不会损失准确性。空格被忽略。

例子

  • "0 10000000 10010010000111111011011"变成3.141592一个float
  • "1 11111111 00000000000000000000000"变成-infinity.
  • "0 11111111 10010010000111111011011"变成浮点数 NaN
  • "1 10000000000 0101101111110000101010001011000101000101011101101001"
    成为最接近-e的双精度值,即2.71828182845904509079559829843

到目前为止,我有大量代码:

public static double ieee(String binString) throws Exception {
    binString = binString.replace(" ", "");
    if (binString.length() == 32) {
        String exponentB = binString.substring(1, 9);
        String mantissaB = binString.substring(9, 32);
        int sgn = binString.charAt(0) == '0' ? 1 : -1;
        int exponent = Integer.parseInt(exponentB, 2) - 127; // Biased by 127
        double mantissa = 1 + Integer.parseInt(mantissaB, 2) / Math.pow(2, 23);

        if (exponent == 128 && mantissa == 1)
            return sgn == 1 ? Double.POSITIVE_INFINITY : Double.NEGATIVE_INFINITY;
        if (exponent == 128 && mantissa != 0)
            return Double.NaN;
        if (exponent == -127)
            return sgn*Math.pow(2,-126)*(mantissa - 1);
        return sgn*Math.pow(2, exponent)*mantissa;
    }
    else if (binString.length() == 64) {
        String exponentB = binString.substring(1, 12);
        String mantissaB = binString.substring(12, 64);
        int sgn = binString.charAt(0) == '0' ? 1 : -1;
        int exponent = Integer.parseInt(exponentB, 2) - 1023; // Biased by 1023
        double mantissa = 1 + Long.parseLong(mantissaB, 2) / Math.pow(2, 52);

        if (exponent == 1024 && mantissa == 1)
            return sgn == 1 ? Double.POSITIVE_INFINITY : Double.NEGATIVE_INFINITY;
        if (exponent == 1024 && mantissa != 0)
            return Double.NaN;
        if (exponent == -1023)
            return sgn*Math.pow(2,-1022)*(mantissa - 1);
        return sgn*Math.pow(2, exponent)*mantissa;
    }
    else {
        throw new Exception("Does not represent internal bits of a floating-point number");
    }
}
Run Code Online (Sandbox Code Playgroud)

虽然我的代码现在可以工作,但就速度和代码量而言,将 IEEE-754 二进制表示形式 String 转换为其floator的最简洁或最快的方法是什么?double首选最有效的方法,并对其效率和专业知识有很好的解释。

Ste*_*n C 6

这种方法可能更有效。它当然更简单且更易于维护。

  1. 从字符串中删除空格
  2. 验证字符串长度...
  3. 将二进制字符串转换为int
  4. 调用Float.intBitsToFloat(int)以转换为float.

对于双打,使用long和 等效Double方法。


简化后的代码是不是效率更高?

唯一确定的方法就是对其进行基准测试。但根据你的代码正在做什么,我相信是这样的。

  • 1) 随意编写您自己的基准测试:-) 2) 是的。我的方法避免了所有这些混乱的事情。在底层,“intBitsToFloat”将是一个简单的赋值。 (2认同)