IEEE754在Java中的浮点算法以及说明实现

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

运行截图如下

  • 7
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值