Alberto Rossi
Alberto Rossi

Reputation: 1800

Convert decimal to IEEE Binary

I am trying to convert a number from decimal value to its IEEE 752 form. For example:

+43.9542 -> 01000010001011111101000100011010
-43.9542 -> 11000010001011111101000100011010

And I have written this method:

public float GetFloat32(String numero) {  

        //Convert
        int intBits = Integer.parseInt(numero, 2);
        float myFloat = Float.intBitsToFloat(intBits);

        //Exponent
        getExponent = 127 + (String.valueOf(Integer.toBinaryString(Math.abs((int) myFloat))).length() - 1);

        //Sign
        getSign = (myFloat < 0) ? 1 : 0;

        return myFloat;
    } 

There is a problem that I cannot solve. I will make another example to make it clear.

double a = k.GetFloat32("01000010001011111101000100011010")
a = 43.9542

But when the number is negative, such as

double a = k.GetFloat32("1000010001011111101000100011010")

I get this error:

Error message

It means that my code works perfectly with positive numbers (including the zero) but with negative numbers it crashes. Where is the problem?

Note

I thought that I could solve my problem in this way

  1. Check if String numero has a charAt(0) equal at 1
  2. If yes (numero.charAt(0) == 1) then remove the first char
  3. Call GetFloat32() with the new number (without the 1)
  4. Return the result adding the - in front of the num

This could work but I would like to know where is the problem in the method above. I'd prefer avoiding this solution if possible.

Upvotes: 0

Views: 1712

Answers (3)

Karthikeya S R
Karthikeya S R

Reputation: 1

public class IEEE754ToFloatingValues {

public static double convertToInt(String mantissa_str) {
    
    int power_count = -1;
    double mantissa_int = 0.0;
    for (int i = 0; i < mantissa_str.length(); i++) {
        // System.out.print(Integer.parseInt(mantissa_str.charAt(i) + ""));
        mantissa_int += (Integer.parseInt(mantissa_str.charAt(i) + "") * Math.pow(2, power_count));
        power_count -= 1;
    }

    IEEE754ToFloatingValues.logger.info((Object) "IEEE754ToFloatingValues : convertToInt :: end");

    return mantissa_int + 1.0;
}

public static String convertToBinary(int i) {
    
    return Integer.toBinaryString(i + 0b10000).substring(1);
}

public static String decimalToHex(String decimal) {

    int i = Integer.parseInt(decimal);
    System.out.println("<<>>" + i);
    String my_hexdata = Integer.toHexString(i);

    System.out.println(my_hexdata);

    return String.valueOf(ReturnFloatingValue(my_hexdata));

}

public static double ReturnFloatingValue(String my_hexdata) {

    

    String myString = "";
    if (my_hexdata == null) {
        return -2.0;
    }
    if (my_hexdata.length() != 8) {
        myString = String.format("%1$-" + 8 + "s", my_hexdata).replace(' ', '0');

        System.out.println("My hex data after appending 0's is : " + myString);
    }

    String binary = "";
    for (int i = 0; i < myString.length(); i++) {
        int num = Integer.parseInt(myString.charAt(i) + "", 16);
        binary += convertToBinary(num);
    }

    System.out.println("Binary length is :  " + binary.length());

    System.out.println("Binary number is : " + binary);
    if (binary == null || binary.isEmpty()) {

        return -3.0;
    }
    String ieee_32 = binary.substring(2);

    ieee_32 = String.format("%1$-32s", binary).replace(' ', '0');

    long sign_bit = Long.parseLong(new StringBuilder().append(ieee_32.charAt(0)).toString());

    long exponent_bias = Long.parseLong(ieee_32.substring(1, 9),    long exponent_unbias = exponent_bias - 127L;

    System.out.println("Exponent unbias is  : " + exponent_unbias);
    String mantissa_str = ieee_32.substring(9);

    double mantissa_int = convertToInt(mantissa_str);
    double real_no = Math.pow(-1.0, (double) sign_bit) * mantissa_int * Math.pow(2.0, (double) exponent_unbias);

    System.out.println("Real no is : " + real_no);
    return real_no;
}

public static void main(String[] args) {

    //decimalToHex("0");
}

}

Upvotes: 0

NINGANNA KUNTOJI
NINGANNA KUNTOJI

Reputation: 1

import java.util.*;

public class IEEE754 {

    public static void main(String[] args) {

        float floa;

        Scanner sc = new Scanner(System.in);

        System.out.println("ENTER A FLOATING POINT NUMBER");

        floa=sc.nextFloat();

        int no,sign;

        no=(int) floa;

        String a= Integer.toBinaryString(no);

        String sub=a.substring(1, a.length());

        if(floa<0)

        {

           sign=1;

        }

        else

        {

            sign=0;

        }

        int exp=a.length()-1;

        System.out.println(exp);

        int be=127+exp;

        String b= Integer.toBinaryString(be);

        System.out.print("biased exponent->");

        System.out.println(b);

        int loop=23-exp;

        float floatpart =floa-no;

        int q[]=new int[25];

        for(int i=1,j=0;i<=loop;i++,j++)

        {

            q[j]=(int) (floatpart*2);

            floatpart=floatpart*2;

            if(q[j]==1){

               floatpart=floatpart-1;

            }

        }

        System.out.print("mantissa->");

        System.out.print(sub);

        for(int k=0;k<q.length;k++)

        System.out.print(q[k]);

            System.out.println();

                        System.out.println("IEEE754 FORMAT IS");

                        System.out.print(sign+" "+b+" ");

                        System.out.print(sub);

        for(int k=0;k<q.length;k++)

        System.out.print(q[k]);

    }

}

Upvotes: -1

laune
laune

Reputation: 31290

The problem is that int/Integer has an upper limit of 0x7FFF_FFFF and so the Integer.parseInt method won't go beyond this limit.

Use Long.parseLong, check the resulting value for exceeding 0x7FFF_FFFFL and handle according to the logic required for negative integer values.

Although, I don't see anything bad in your very own idea of stripping the sign bit and dealing with the rest to get the absolute value.

Edit There isn't a way to get the encoded float with a simple integer conversion from a bit string. Just consider that +1 and -1 in 32 binary digits according to two's complement representation differ in more than one bit, and 100....000 isn't -0. Signed magnitude isn't the same as two's complement. Moreover, Java's binary and hexadecimal (or any other base's) literals are meant to be positive quantities; if you need a negative value, use a sign.

Later Method Integer.parseUnsignedInt doesn't have an advantage over using Long, since you'll then have to know how use two's complement arithmetic to remove the leading (sign) bit to produce the absolute value which can then be split into exponent and mantissa. (Add or subtract Integer.MIN_VALUE.)

If there isn't IEEE 752 and IEEE 754 is the target format, the easiest form is

float f1 = Float.intBitsToFloat(Integer.parseUnsignedInt(numerio,2));

Upvotes: 3

Related Questions