Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I convert an IEEE-754 binary representation String to a float or double in Java?

Since all Java floating-point numbers, which are floats and doubles, are internally represented as bits, I want to find an efficient algorithm to convert a String representing the bits of that float or double and convert it into its corresponding floating-point number - I couldn't find a built-in library function for it so I resorted to writing it by myself.

A binary String of length 32 represents a float, where as a binary String of length 64 will be converted to a double. All floats can be converted to doubles without loss of accuracy. Spaces are ignored.

Examples

  • "0 10000000 10010010000111111011011" becomes 3.141592 as a float.
  • "1 11111111 00000000000000000000000" becomes -infinity.
  • "0 11111111 10010010000111111011011" becomes a float NaN.
  • "1 10000000000 0101101111110000101010001011000101000101011101101001"
    becomes a double value closest to -e, which is 2.71828182845904509079559829843

So far I have this mass of a code:

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

Though my code works as of now, what is the neatest or fastest method to convert a IEEE-754 binary representation String to its float or double, in terms of speed and amount of code? The most efficient method with a good explanation of its efficiency and expertise is preferred.

like image 319
Ṃųỻịgǻňạcểơửṩ Avatar asked Oct 17 '25 13:10

Ṃųỻịgǻňạcểơửṩ


1 Answers

This approach is probably more efficient. It is certainly simpler and more maintainable.

  1. Remove spaces from string
  2. Validate string length ...
  3. Convert binary string to int
  4. Call Float.intBitsToFloat(int) to convert to an float.

For doubles, use long and the equivalent Double method.


Is the simplified code more efficient?

The only way to be sure is to benchmark it. But based on what your code is doing, I believe so.

like image 113
Stephen C Avatar answered Oct 19 '25 05:10

Stephen C