Programming03

题目大意

ALU.javaFPU.java中完成乘法部分


ALU部分

取成64位的串,调用一下之前写过的加法和位移,最后截取低32位就好了。

代码很简单,稍微抄了一下之前取补码的那个方法:

public class ALU {
    private StringBuilder ans=new StringBuilder();
    public static String getComplement(String tar) {
        tar = tar.replace("0", "2").replace("1", "0").replace("2", "1");
        char[] status = tar.toCharArray();
        for (int i = tar.length() - 1, jud = 1; i >= 0; i--) {
            status[i] = (char) ((jud ^ (tar.charAt(i) - '0')) + '0');
            jud = ((tar.charAt(i) - '0') & jud);
        }
        return Arrays.toString(status).replaceAll("[\\[\\]\\s,]", "");
    }
    String add(String src, String dest) {
        ans=new StringBuilder();
        int c=0,s=0;
        for(int i=dest.length()-1;i>=0;i--){
            int x=src.charAt(i)-'0',y=dest.charAt(i)-'0';
            s=x^y^c;
            c=(x&c)|(y&c)|(x&y);
            ans.append(s);
        }
        return ans.reverse().toString();
    }
    String shift(String src){
        return (src.charAt(0)=='1'?"1":"0")+src.substring(0,src.length()-1);
    } //特殊的位移一位方法
    
    /**
     * 返回两个二进制整数的乘积(结果直接截取后32位)
     * 要求使用布斯乘法计算
     * @param src 32-bits
     * @param dest 32-bits
     * @return 32-bits
     */
    String mul (String src, String dest,String...args){
        dest="00000000000000000000000000000000"+dest+"0";
        String rev=getComplement(src);
        src=src+"000000000000000000000000000000000";
        rev=rev+"000000000000000000000000000000000";//33个零,扩展到65位
        for(int i=0;i<32;i++){
            if(dest.charAt(64)-dest.charAt(63)==1)
                dest=add(src,dest);
            else if(dest.charAt(64)-dest.charAt(63)==-1)
                dest=add(rev,dest);
            dest=shift(dest);
        }
        if(args.length==0)
            return dest.substring(32,64);
        else return dest;
    }

}   

FPU部分

这部分怎么说呢,指数相加,但是注意相当于多加了一个bias,直接加的结果要减去对应的这个bias.想来助教应该不会刁钻到出float的非规约形式,即0.significant的结构,因此直接在23位前补上1.就好了。同时看了看测试样例,可以说是非常弱的数据,所以指数不用考虑溢出直接写就好了。

写的是否发现要注意一下a为0的情况,需要判断b是Inf或NaN:

package cpu.alu;

import util.IEEE754Float;

import java.util.regex.Pattern;

/**
 * floating point unit
 * 执行浮点运算的抽象单元
 * 浮点数精度:使用4位保护位进行计算,计算完毕直接舍去保护位
 * TODO: 浮点数运算
 */
public class FPU {

    /**
     * compute the float mul of a * b
     * 分数部分(23 bits)的计算结果直接截取前23位
     */
    String mul(String a, String b) {
        char flag=a.charAt(0)==b.charAt(0)?'0':'1';
        if(Pattern.matches("0{31}",a.substring(1,32)))
            if(Pattern.matches("1{8}",b.substring(1,9)))
                return "(0|1){1}1{8}(0+1+|1+0+)(0|1)*";
            else return flag+a.substring(1,32);
        ALU alu=new ALU();
        String ex=alu.add(a.substring(1,9),alu.add(b.substring(1,9),"10000001"));
        String sig=alu.mul("000000001"+a.substring(9,32),"000000001"+b.substring(9,32),"not cut");
        return flag+ex+sig.substring(sig.indexOf('1')+1,sig.indexOf('1')+24);
    }

}

测试一下,都通过了。

你可能感兴趣的:(Programming03)