先贴代码
/**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;
}
}