Programming04

題目大意

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


補(bǔ)碼除法

不覆蓋reminder的算法遭笋,根據(jù)PPT上給出的步驟算就好了:

  • Extend the dividend by adding n bits sign in the front, and store it in the remainder and quotient registers

  • If dividend has the same sign with divisor, do subtraction; otherwise, do addition

    • If the remainder has same sign with divisor, Qn=1; otherwise, Qn= 0
  • If the remainder has the same sign with divisor , Ri+1=2Ri-Y; otherwise, Ri+1=2Ri+Y

    • If the new remainder has the same sign to divisor, set quotient to 1; otherwise, set quotient to 0
  • Repeat the above step

  • Left shift quotient, if quotient is negative (the dividend has the different sign with divisor), quotient adds 1

  • The remainder has the different sign with dividend

    • Remainder adds divisor if the dividend has the same sign with divisor, and subtracts divisor otherwise

但是要注意一下這個(gè)算法實(shí)際上是會(huì)留下一個(gè)余數(shù)的并且這個(gè)余數(shù)可能會(huì)等于除數(shù)坝冕,所以要進(jìn)行判斷一下,把商加上1或-1(由被除數(shù)的符號(hào)決定)瓦呼。

代碼如下:

public class ALU {

    // 模擬寄存器中的進(jìn)位標(biāo)志位
    private String CF = "0";

    // 模擬寄存器中的溢出標(biāo)志位
    private String OF = "0";

    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.substring(1)+"0";
    } //特殊的位移一位方法

    /**
     * 返回兩個(gè)二進(jìn)制整數(shù)的除法結(jié)果 operand1 ÷ operand2
     * @param operand1 32-bits
     * @param operand2 32-bits
     * @return 65-bits overflow + quotient + remainder
     */
    String div(String operand1, String operand2) {
        if(Pattern.matches("0{32}",operand2)){
            if(!Pattern.matches("0{32}",operand1))
                throw new ArithmeticException();
            else return BinaryIntegers.NaN;
        }else if(Pattern.matches("0{32}",operand1)) {
            return "0"+BinaryIntegers.ZERO+BinaryIntegers.ZERO;
        }

        char flag1=operand1.charAt(0);
        char flag2=operand2.charAt(0);
        String divisor=operand2+"000000000000000000000000000000000"; //divisor=高32位+低32位0+商末尾補(bǔ)充位0
        String rev=getComplement(operand2)+"000000000000000000000000000000000";// -divisor=高32位補(bǔ)碼+低32位0+商末尾補(bǔ)充位0
        String ans=(operand1.charAt(0)=='1'?"11111111111111111111111111111111":"00000000000000000000000000000000")+
                    operand1+"0"; //高32位符號(hào)位+低32位被除數(shù)+補(bǔ)充位0
        if(flag1==flag2)
            ans=add(ans,rev);
        else ans=add(ans,divisor);
        if(ans.charAt(0)==flag2) {
            ans=ans.substring(0,ans.length()-1)+"1";
        }
        for(int i=0;i<32;i++){
            if(ans.charAt(0)==flag2) {
                ans=shift(ans);
                ans=add(ans,rev);
            }else{
                ans=shift(ans);
                ans=add(ans,divisor);
            }
            if(ans.charAt(0)==flag2)
                ans=ans.substring(0,ans.length()-1)+"1";
        }
        String quotient=ans.substring(32,65);
        String reminder=ans.substring(0,32);
        quotient = shift(quotient).substring(0,32);
        if(quotient.charAt(0)=='1')
            quotient = add(quotient, "00000000000000000000000000000001");
        if(reminder.charAt(0)!=flag1) {
            if (flag1 == flag2)
                reminder = add(reminder, operand2);
            else
                reminder=add(reminder,getComplement(operand2));
        }
        if(reminder.equals(getComplement(operand2))){
            reminder="00000000000000000000000000000000";
            quotient=add(quotient,getComplement("00000000000000000000000000000001"));
        }else if(reminder.equals(operand2)) {
            reminder="00000000000000000000000000000000";
            quotient=add(quotient, "00000000000000000000000000000001");
        }
        return (flag2!='0'&&flag1==flag2&&quotient.charAt(0)==flag1?"1":"0")+quotient+reminder;
    }

}

Float除法

暫時(shí)不考慮0.significant形式的小數(shù)喂窟,處理方法類似于乘法,處理指數(shù)+截取小數(shù)除法的前23位央串。

要稍微注意一下磨澡,這里的除法相當(dāng)于把小數(shù)部分統(tǒng)一成了1.xxxxx/1.xxxxx,那么答案要么是0余若干數(shù)质和,要么是1余若干數(shù)稳摄,因此我們把返回的商的末位,補(bǔ)到擴(kuò)充significant時(shí)加上的0的個(gè)數(shù)對(duì)應(yīng)的位數(shù)之后饲宿。

00001[補(bǔ)充了4個(gè)0]+significant+0000[保護(hù)位]厦酬,那么最后截取的應(yīng)該是:

(quotient.charAt(end-1)+reminder[4...]).substring(indexOf('1')+1,indexOf('1')+24)

如果indexOf('1')不為0,還需要加到ex上褒傅。

代碼如下:

public class FPU {

    /**
     * compute the float mul of a / b
     */
    String div(String a, String b) {
        char flag=a.charAt(0)==b.charAt(0)?'0':'1';
        if(Pattern.matches("[01]0{31}",b))
            if(Pattern.matches("[01]0{31}",a)) return IEEE754Float.NaN;
            else throw new ArithmeticException();
        if(Pattern.matches("1{8}0{23}",a.substring(1,a.length()))||Pattern.matches("[01]0{31}",a))
            return flag+a.substring(1,a.length());
        ALU alu=new ALU();
        String ex=alu.add(a.substring(1,9),alu.add(ALU.getComplement(b.substring(1,9)),"01111111"));
        String sig=alu.div("00001"+a.substring(9,32)+"0000","00001"+b.substring(9,32)+"0000");
        sig=sig.charAt(32)+sig.substring(38);
        for(int i=0;i<sig.indexOf('1');i++)
            ex=alu.add(ex,"11111111");
        return flag+ex+sig.substring(sig.indexOf('1')+1,sig.indexOf('1')+24);
    }

}

其實(shí)測(cè)試樣例挺弱的弃锐,很簡(jiǎn)單就過了。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末殿托,一起剝皮案震驚了整個(gè)濱河市霹菊,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌支竹,老刑警劉巖旋廷,帶你破解...
    沈念sama閱讀 211,123評(píng)論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異礼搁,居然都是意外死亡饶碘,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,031評(píng)論 2 384
  • 文/潘曉璐 我一進(jìn)店門馒吴,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)扎运,“玉大人,你說我怎么就攤上這事饮戳『乐危” “怎么了?”我有些...
    開封第一講書人閱讀 156,723評(píng)論 0 345
  • 文/不壞的土叔 我叫張陵扯罐,是天一觀的道長(zhǎng)负拟。 經(jīng)常有香客問我,道長(zhǎng)歹河,這世上最難降的妖魔是什么掩浙? 我笑而不...
    開封第一講書人閱讀 56,357評(píng)論 1 283
  • 正文 為了忘掉前任花吟,我火速辦了婚禮,結(jié)果婚禮上厨姚,老公的妹妹穿的比我還像新娘衅澈。我一直安慰自己,他們只是感情好遣蚀,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,412評(píng)論 5 384
  • 文/花漫 我一把揭開白布矾麻。 她就那樣靜靜地躺著,像睡著了一般芭梯。 火紅的嫁衣襯著肌膚如雪险耀。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,760評(píng)論 1 289
  • 那天玖喘,我揣著相機(jī)與錄音甩牺,去河邊找鬼。 笑死累奈,一個(gè)胖子當(dāng)著我的面吹牛贬派,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播澎媒,決...
    沈念sama閱讀 38,904評(píng)論 3 405
  • 文/蒼蘭香墨 我猛地睜開眼搞乏,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了戒努?” 一聲冷哼從身側(cè)響起请敦,我...
    開封第一講書人閱讀 37,672評(píng)論 0 266
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎储玫,沒想到半個(gè)月后侍筛,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,118評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡撒穷,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,456評(píng)論 2 325
  • 正文 我和宋清朗相戀三年匣椰,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片端礼。...
    茶點(diǎn)故事閱讀 38,599評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡禽笑,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出蛤奥,到底是詐尸還是另有隱情蒲每,我是刑警寧澤,帶...
    沈念sama閱讀 34,264評(píng)論 4 328
  • 正文 年R本政府宣布喻括,位于F島的核電站,受9級(jí)特大地震影響贫奠,放射性物質(zhì)發(fā)生泄漏唬血。R本人自食惡果不足惜望蜡,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,857評(píng)論 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望拷恨。 院中可真熱鬧脖律,春花似錦、人聲如沸腕侄。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,731評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)冕杠。三九已至微姊,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間分预,已是汗流浹背兢交。 一陣腳步聲響...
    開封第一講書人閱讀 31,956評(píng)論 1 264
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留笼痹,地道東北人配喳。 一個(gè)月前我還...
    沈念sama閱讀 46,286評(píng)論 2 360
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像凳干,于是被迫代替她去往敵國(guó)和親晴裹。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,465評(píng)論 2 348

推薦閱讀更多精彩內(nèi)容