java - 如何在 Java 中将 IEEE-754 二进制表示字符串转换为 float 或 double ?

标签 java string floating-point ieee-754 string-parsing

由于所有 Java float ,即floatsdoubles,在内部都表示为位,我想找到一个高效的用于转换表示 floatdouble 位的字符串并将其转换为相应的 float 的算法 - 我找不到一个内置的库函数,所以我求助于自己编写它。

长度为 32 的二进制字符串表示一个 float ,而长度为 64 的二进制字符串将被转换为一个 double 。所有floats 都可以转换为double 而不会损失准确性。忽略空格。

示例

  • "0 10000000 10010010000111111011011" 变成 3.141592 float
  • “1 11111111 00000000000000000000000” 变为 -infinity
  • "0 11111111 10010010000111111011011" 变为 float NaN
  • "1 10000000000 0101101111110000101010001011000101000101011101101001"
    成为最接近-edouble值,即2.7182818284590 4509079559829843

到目前为止,我有这么一大堆代码:

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");
    }
}

尽管我的代码目前有效,但将 IEEE-754 二进制表示字符串转换为其 floatdouble 的最简洁或最快的方法是什么?速度和代码量?优先考虑最有效的方法,并对其效率和专业知识进行很好的解释。

最佳答案

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

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

对于 double ,使用long 和等效的Double 方法。


Is the simplified code more efficient?

唯一可以确定的方法是对其进行基准测试。但根据您的代码所做的,我相信是这样。

关于java - 如何在 Java 中将 IEEE-754 二进制表示字符串转换为 float 或 double ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51371033/

相关文章:

java - JPA REQUIRES_NEW 事务到底什么时候提交

java - 如何在 Spring MVC 中进行模型部分?

string - 带引号和不带引号的 bash 字符串有什么区别

c - 从c中的字符串中删除所有重复的字符

java - 从文本文件打印最小的人 - Java

java - 通过事件添加带有 JTabbedPane 的新选项卡

arrays - 如何在 hive sql 中将数组转换为字符串?

floating-point - FSIN 和其他 x87 三角函数指令在 AMD 处理器上的准确性

python - 如何获得小数点后的数字?

c++ - 无效的静态断言行为