简体   繁体   English

将十进制转换为 IEEE 二进制

[英]Convert decimal to IEEE Binary

I am trying to convert a number from decimal value to its IEEE 752 form.我正在尝试将数字从十进制值转换为其 IEEE 752 形式。 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:我收到此错误:

错误信息

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检查String numero的 charAt(0) 是否等于 1
  2. If yes (numero.charAt(0) == 1) then remove the first char如果是 (numero.charAt(0) == 1) 则删除第一个字符
  3. Call GetFloat32() with the new number (without the 1)使用新号码(不带 1)调用 GetFloat32()
  4. Return the result adding the - in front of the num返回在 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.如果可能的话,我宁愿避免这种解决方案。

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.问题是 int/Integer 的上限为 0x7FFF_FFFF,因此 Integer.parseInt 方法不会超出此限制。

Use Long.parseLong, check the resulting value for exceeding 0x7FFF_FFFFL and handle according to the logic required for negative integer values.使用 Long.parseLong,检查结果值是否超过 0x7FFF_FFFFL 并根据负整数值所需的逻辑进行处理。

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.只需考虑根据二进制补码表示的 32 个二进制数字中的 +1 和 -1 的差异不止一位,并且 100....000 不是 -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;此外,Java 的二进制和十六进制(或任何其他基数)字面量都是正数; 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.后来的方法 Integer.parseUnsignedInt 与使用 Long 相比没有优势,因为您必须知道如何使用二进制补码算法来删除前导(符号)位以产生绝对值,然后可以将其拆分为指数和尾数. (Add or subtract Integer.MIN_VALUE.) (加或减 Integer.MIN_VALUE。)

If there isn't IEEE 752 and IEEE 754 is the target format, the easiest form is如果没有 IEEE 752 并且 IEEE 754 是目标格式,最简单的形式是

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

public class IEEE754ToFloatingValues {公共类 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");
}

} }

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]);

    }

}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM