java中,IEEE754标准(四字节)的字节数据和浮点数之间的转化(Float and byte[])

先贴代码

/**java实现IEEE 754标准
 * 16进制转float
 * @author wp
 *
 */
public class Hex2Float {
	
	
	public static void main(String[] args) {
		
		System.out.println(bytes2Float(ByteConvertUtil.hexStringToBytes("C2480000")));
		System.out.println(bytes2float(ByteConvertUtil.hexStringToBytes("C2480000")));
		
	}
	
	/**
	 * 字节数组转float
	 * 采用IEEE 754标准
	 * @param bytes
	 * @return
	 */
	public static float bytes2Float(byte[] bytes){
		//获取 字节数组转化成的2进制字符串
		String BinaryStr = bytes2BinaryStr(bytes);
		//符号位S
		Long s = Long.parseLong(BinaryStr.substring(0, 1));
		//指数位E
		Long e = Long.parseLong(BinaryStr.substring(1, 9),2);
		//位数M
		String M = BinaryStr.substring(9);
		float m = 0,a,b;
		for(int i=0;i<M.length();i++){
			a = Integer.valueOf(M.charAt(i)+"");
			b = (float) Math.pow(2, i+1);
			m =m + (a/b);
		}
		Float f = (float) ((Math.pow(-1, s)) * (1+m) * (Math.pow(2,(e-127))));
		return f;
	}
	/**
	 * 将字节数组转换成2进制字符串
	 * @param bytes
	 * @return
	 */
	public static String bytes2BinaryStr(byte[] bytes){
		StringBuffer binaryStr = new StringBuffer();
		for(int i=0;i<bytes.length;i++){
			String str = Integer.toBinaryString((bytes[i] & 0xFF) + 0x100).substring(1);
			binaryStr.append(str);
		}
		return binaryStr.toString();
	}
	
 
	public static float bytes2float(byte[] bytes){
		String hexString = ByteConvertUtil.bytes2HexString(bytes);
		Long l = Hex2Float.parseLong(hexString, 16);
		Float f = Float.intBitsToFloat(l.intValue());
		return f;
	}
	public static long parseLong(String s, int radix) throws NumberFormatException {
		if (s == null) {
			throw new NumberFormatException("null");
		}
 
		if (radix < Character.MIN_RADIX) {
			throw new NumberFormatException("radix " + radix + " less than Character.MIN_RADIX");
		}
		if (radix > Character.MAX_RADIX) {
			throw new NumberFormatException("radix " + radix + " greater than Character.MAX_RADIX");
		}
 
		long result = 0;
		boolean negative = false;
		int i = 0, len = s.length();
		long limit = -Long.MAX_VALUE;
		long multmin;
		int digit;
 
		if (len > 0) {
			char firstChar = s.charAt(0);
			if (firstChar < '0') { // Possible leading "+" or "-"
				if (firstChar == '-') {
					negative = true;
					limit = Long.MIN_VALUE;
				} else if (firstChar != '+')
					throw NumberFormatException.forInputString(s);
 
				if (len == 1) // Cannot have lone "+" or "-"
					throw NumberFormatException.forInputString(s);
				i++;
			}
			multmin = limit / radix;
			while (i < len) {
				// Accumulating negatively avoids surprises near MAX_VALUE
				digit = Character.digit(s.charAt(i++), radix);
				if (digit < 0) {
					throw NumberFormatException.forInputString(s);
				}
				if (result < multmin) {
					throw NumberFormatException.forInputString(s);
				}
				result *= radix;
				if (result < limit + digit) {
					throw NumberFormatException.forInputString(s);
				}
				result -= digit;
			}
		} else {
			throw NumberFormatException.forInputString(s);
		}
		return negative ? result : -result;
	}
}
 
class NumberFormatException extends IllegalArgumentException {
	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
 
	public NumberFormatException(String s) {
		super(s);
	}
 
	static NumberFormatException forInputString(String s) {
		return new NumberFormatException("For input string: \"" + s + "\"");
	}
}

输出结果:

-50.0
-50.0

在项目中与终端的进行数据传输,在遇到的浮点型数据的时候,碰到了java不像整型那样好操作。协议中只提供了标准“IEEE 754”, 咦,对于菜鸟学渣来说这是个啥…… 上网查找:

在这里插入图片描述
**

再具体的底层什么协议,先不管了,让我先画个瓢。

**

/**
	 * 字节数组转float
	 * 采用IEEE 754标准
	 * @param bytes
	 * @return
	 */
	public static float bytes2Float(byte[] bytes){
		//获取 字节数组转化成的16进制字符串
		String BinaryStr = bytes2BinaryStr(bytes);
		//符号位S
		Long s = Long.parseLong(BinaryStr.substring(0, 1));
		//指数位E
		Long e = Long.parseLong(BinaryStr.substring(1, 9),2);
		//位数M
		String M = BinaryStr.substring(9);
		float m = 0,a,b;
		for(int i=0;i<M.length();i++){
			a = Integer.valueOf(M.charAt(i)+"");
			b = (float) Math.pow(2, i+1);
			m =m + (a/b);
		}
		Float f = (float) ((Math.pow(-1, s)) * (1+m) * (Math.pow(2,(e-127))));
		return f;
	}
	/**
	 * 将字节数组转换成16进制字符串
	 * @param bytes
	 * @return
	 */
	public static String bytes2BinaryStr(byte[] bytes){
		StringBuffer binaryStr = new StringBuffer();
		for(int i=0;i<bytes.length;i++){
			String str = Integer.toBinaryString((bytes[i] & 0xFF) + 0x100).substring(1);
			binaryStr.append(str);
		}
		return binaryStr.toString();
	}

多次测试没有问题。然后在网上还找到一段代码,在这贴出来。 自己写的代码肯定又不好的地方,或者是丢失精度等问题,欢迎大家批评指正。

不说了,简单记录下,剥削者来了~~~

补充方法:

import java.math.BigInteger;

import io.netty.buffer.ByteBuf;

public class ByteConvertUtil {
	/**  
	    * 将int数值转换为占四个字节的byte数组,本方法适用于(低位在前,高位在后)的顺序。 和bytesToInt()配套使用 
	    * @param value  
	    *            要转换的int值 
	    * @return byte数组 
	*/    
	public static byte[] intToBytes( int value )   
	{   
	    byte[] src = new byte[4];  
	    src[3] =  (byte) ((value>>24) & 0xFF);  
	    src[2] =  (byte) ((value>>16) & 0xFF);  
	    src[1] =  (byte) ((value>>8) & 0xFF);    
	    src[0] =  (byte) (value & 0xFF);                  
	    return src;   
	} 
	
	/**  
	    * 将int数值转换为占四个字节的byte数组,本方法适用于(高位在前,低位在后)的顺序。  和bytesToInt2()配套使用 
	*/    
	public static byte[] intToBytes2(int value)   
	{   
	    byte[] src = new byte[4];  
	    src[0] = (byte) ((value>>24) & 0xFF);  
	    src[1] = (byte) ((value>>16)& 0xFF);  
	    src[2] = (byte) ((value>>8)& 0xFF);    
	    src[3] = (byte) (value & 0xFF);       
	    return src;  
	}  
	
	/**  
	    * byte数组中取int数值,本方法适用于(低位在前,高位在后)的顺序,和和intToBytes()配套使用 
	    *   
	    * @param src  
	    *            byte数组  
	    * @param offset  
	    *            从数组的第offset位开始  
	    * @return int数值  
	*/    
	public static int bytesToInt(byte[] src, int offset) {  
	    int value;    
	    value = (int) ((src[offset] & 0xFF)   
	            | ((src[offset+1] & 0xFF)<<8)   
	            | ((src[offset+2] & 0xFF)<<16)   
	            | ((src[offset+3] & 0xFF)<<24));  
	    return value;  
	}  
	  
	/**  
	    * byte数组中取int数值,本方法适用于(低位在后,高位在前)的顺序。和intToBytes2()配套使用 
	 */  
	public static int bytesToInt2(byte[] src, int offset) {  
	    int value;    
	    value = (int) ( ((src[offset] & 0xFF)<<24)  
	            |((src[offset+1] & 0xFF)<<16)  
	            |((src[offset+2] & 0xFF)<<8)  
	            |(src[offset+3] & 0xFF));  
	    return value;  
	}  
	
	/**
	 * 16进制转换为字节流
	 * @param hexString
	 * @return
	 */
	public static byte[] hexStringToBytes(String hexString) {     
     if (hexString == null || hexString.equals("")) {     
         return null;     
      }     
      hexString = hexString.toUpperCase();     
      int length = hexString.length() / 2;     
      char[] hexChars = hexString.toCharArray();     
     byte[] d = new byte[length];     
      for (int i = 0; i < length; i++) {     
          int pos = i * 2;     
        d[i] = (byte) (charToByte(hexChars[pos]) << 4 | charToByte(hexChars[pos + 1]));     
      }     
      return d;     
 }

/**
	 * 字节流转换为字符串
	 * @return
	 */
	public static String bytes2HexString(byte[] bytes){
		StringBuffer sb = new StringBuffer();
		for(int i = 0 ; i < bytes.length; i++){
			int first = (bytes[i] & 0xFF) >> 4;
			int second = (bytes[i] & 0xFF) & 0x0F;
			sb.append(int2Char(first));
			sb.append(int2Char(second));
		}
		return sb.toString();
	}
	
 private static byte charToByte(char c) {     
     return (byte) "0123456789ABCDEF".indexOf(c);     
 }  
 
 private static char int2Char(int data){
 	String str = "0123456789ABCDEF";
 	return str.charAt(data);
 }
 
	/**
	 * 所有字节参与异或运算
	 * @param obj
	 * @return
	 */
	public static byte getCheckResult(byte[] bytes){
		byte result = bytes[0];
		for(int i = 1; i < bytes.length; i++){
			result ^= bytes[i];
		}
		return result;
	}

	/**
	 * 二进制相加
	 * @param a
	 * @param b
	 * @return
	 */
	public static String addBinary(String a, String b) {
     String result="";
     //类似于前一章的carry进位状态符
     int sum=0;
     int lengthA=a.length();
     int lengthB=b.length();
     while(lengthA>0||lengthB>0){
         if(lengthA>0){
             //截取字符串最后一位,类似获取十进制里的个位
             sum+=Integer.parseInt(a.substring(lengthA-1,lengthA));
             lengthA--;
         }
         if(lengthB>0){
             sum+=Integer.parseInt(b.substring(lengthB-1,lengthB));
             lengthB--;
         }
         //当刚好满足二进制进位条件时
         if(sum==2){
             //相加刚好等于2,所以前一位剩余0,类似于十进制 4+6时,个位满十进位,个位数值为0
             result="0"+result;
             //这里重新赋予1,是指进位的那一个数值,所以前面代码是用 sum+=  而不是sum=
             sum=1;
         }else if(sum==3){
             result="1"+result;
             sum=1;
         }else{
             result=(sum+"")+result;
             sum=0;
         }    
     }
     //用于处理最高位进位
     if(sum==1){
         result = "00000001" + result;
     }
     return result;
 }

/**
	 * 返回二进制
	 * @param udpcontent
	 * @return
	 */
	public static String getAddResultForBytes(ByteBuf udpcontent){
		udpcontent.markReaderIndex();
		String jyh = new BigInteger(1,new byte[]{udpcontent.readByte()}).toString(2);
		for(int i = 1 ; i < 63; i++){
			String tmp = new BigInteger(1,new byte[]{udpcontent.readByte()}).toString(2);
			jyh = addBinary(jyh, tmp);
		}
		udpcontent.resetReaderIndex();
		return jyh;
	}
	/**
	 * 返回二进制
	 * @param byte[] bytes
	 * @return
	 * wp 
	 */
	public static String getAddResultForBytes(byte[] bytes){
		String jyh = new BigInteger(1,new byte[]{bytes[0]}).toString(2);
		for(int i = 1 ; i < 63; i++){
			String tmp = new BigInteger(1,new byte[]{bytes[i]}).toString(2);
			jyh = addBinary(jyh, tmp);
		}
		return jyh;
	}
	/**
	 * byte数组转换为二进制字符串,每个字节以","隔开
	 **/
	public static String byteArrToBinStr(byte[] b) {
	    StringBuffer result = new StringBuffer();
	    for (int i = 0; i < b.length; i++) {
	        result.append(Long.toString(b[i] & 0xff, 2));
	    }
	    return result.toString();
	}

	/**
	 * 二进制字符串转换为byte数组,每个字节以","隔开
	 **/
	public static byte[] binStrToByteArr(String binStr) {
	    String[] temp = binStr.split(",");
	    byte[] b = new byte[temp.length];
	    for (int i = 0; i < b.length; i++) {
	        b[i] = Long.valueOf(temp[i], 2).byteValue();
	    }
	    return b;
	}
}

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值