import java.math.BigDecimal; import java.util.HashMap; import java.util.Map; public class Ieee754Utils { /** * 进制转换方式 * int[] * index 为0 表示符号位占据位数 * index 为1 表示阶码占据位数 * index 为2 表示尾码占据位数 * index 为3 表示偏置码的十进制数 * index 为4 表示字节总长度(十六进制) */ public final static Map<Long,int[]> PARSE_TYPE_MAP; static { PARSE_TYPE_MAP=new HashMap(); PARSE_TYPE_MAP.put(1L,new int[]{1,8,23,127,8}); //单精度 PARSE_TYPE_MAP.put(2L,new int[]{1,11,52,1023,16}); //双精度 PARSE_TYPE_MAP.put(3L,new int[]{1,15,64,16383,20}); //扩展精度浮点数 } /** * 1、其中第一个数据表示正负号 0为正 1为负 记为S * 2、其中第二个数据表示阶码位数(也就是需要用到指数算法的) 记为N * 3、其中第三个数据表示表示尾数位数 M * 4、偏置值为 2^(N-1)-1 即float:127 double:1023 bigdata:16383 * 总公式为:2^(n-(2^(n-1)-1))*(1+m) * 以float为例子 * 详解:十六进制C6370000 * 二进制 1100 0110 0011 0111 0000 0000 0000 0000 * 第一步:其中 第一位1 表示为负数记为 -1 0表示 正数记为1 记变量为a * 第二步:第二位至第九位 100 0110 0 为解码值 即140 记变量为b * 第三步:计算指数部门 140-127 记为 记变量为c * 第四步:计算小数部分 第十位至第三十二位 011 0111 0000 0000 0000 0000 默认前面有个1 * d=(1*2^0+0*2^-1+1*2^-2+1*2^-3+...) * 第五步:带入总公式 a*2^c*d */ public static String getParseTypeData(Long type,String str){ if(PARSE_TYPE_MAP.containsKey(type) && PARSE_TYPE_MAP.get(type)[4] == str.length()){ //偏置码 int[] arr=PARSE_TYPE_MAP.get(type); //正负数求出来了 int fh=Integer.parseInt(str.substring(0,1),16); int a=fh>7?-1:1; if(fh>7){ String s=Integer.toHexString(fh-8).toUpperCase(); str=s+str.substring(1); } long b=Long.parseLong(str,16); //阶码 long c=b>>arr[2]; //尾数的码 long d=c<<arr[2]; long e=b-d;//去掉高位阶码(采用先将后面码全部变为0 然后2个数相减) double f=1+e*Math.pow(2,-1*arr[2]);//采用简便算法 将十进制的值全部算出来 再除以Math.pow(2,位数); double g=a*Math.pow(2,c-arr[3])*f;//采用总公式 return String.valueOf(Double.valueOf(String.format("%.3f",new BigDecimal(g))));//保留三位小数 }; return ""; } public static void main(String[] args) { String str="436BDA25436BB8F3436BE18543CC32A343CC35D443CC443341020FB54121F69441B5D72B44D7DBF644FCF794459E9D11460" + "9E8FA4367B2AD4380851C0000000043F45E7244D9CB2444FEFFD8459E9D11460A1F103F7DB9F43F7DF5B13F8000003F7F9BC1424800" + "00000757620000000000018E13FFFFEA6143E0F772C2F2599B43D0F79FC3CE56091830"; int a=16; long b=2L; for(int i=0;i<Integer.MAX_VALUE;i++){ if((i+1)*a>str.length()){ break; } String str2=str.substring(i*a,i*a+a); String str3= Ieee754Utils.getParseTypeData(b,str2); double v = Double.longBitsToDouble(Long.parseLong(str2,16)); String str4= String.valueOf(Double.valueOf(String.format("%.3f",new BigDecimal(v))));//保留三位小数 System.out.println(str3+"||"+str4); } } }
运行截图如下