浮点数的加减运算

改正:https://blog.csdn.net/duling2/article/details/80788690
#include <iostream>
#include <bitset>
#include <string>
#include <conio.h>
#include <QString>
using namespace std;

const int n=28;

//右移几位 谁右移
std::bitset<n> RightMove
(int RightMoveBit/*右移几位 */,std::bitset<n> WhoRightMove/*谁右移*/)
{
    std::bitset<n> Result;

    WhoRightMove >>=RightMoveBit;

    Result=WhoRightMove;

    return Result;
}

//保存右移时 移出去的位数
std::bitset<n> SaveRightMoveOutBIt
(int RightMoveBit/*右移几位 */,std::bitset<n> WhoRightMove/*谁右移*/,
 int SavedNumber/*以前有保存过的位数*/,std::bitset<n> HasSavedBit)
{
    //以前有右移的话,HasSavedBit里是有东西的
    std::bitset<n> Result;
    int i=0;

    if(SavedNumber>0)
    {
        for(i=0;i<RightMoveBit;i++)
        {
            Result[i]=WhoRightMove[i];
        }
        Result <<=SavedNumber;
        for(i=0;i<SavedNumber;i++)
        {
             Result[i]=HasSavedBit[i];
        }
    }else
    {
        for(i=0;i<RightMoveBit;i++)
        {
            Result[i]=WhoRightMove[i];
        }
    }
    return Result;
}

//取反加1
std::bitset<n> Invert
(int BitNumber/*取反几位*/,std::bitset<n> WhoInvert/*谁取反*/,bool JiaYi)
{
    std::bitset<n> Result;
    std::bitset<n> yihuo;
    int i=0,j=0;
    bool HasAdd=false;
    bool Over=false;

    for(int i=0;i<BitNumber;i++)
    {
          yihuo.set(i);
    }

   std::cout<<"WhoInvert:\t\t\t"<<WhoInvert<<"\n";
   std::cout<<"yihuo:\t\t\t\t"<<yihuo<<"\n";
   WhoInvert=WhoInvert^yihuo;//异或
   std::cout<<"WhoInvert:\t\t\t"<<WhoInvert<<"\n";

 /这里可以设个标志  加不加1//
if(JiaYi)
{
    //加1
    HasAdd=false;
    Over=false;
    i=0;
    j=0;
    while(i<WhoInvert.size())
    {
        if(!HasAdd)
        {
            //1
            if(WhoInvert.test(i))
            {
                WhoInvert.set(i,0);
                HasAdd=true;
                i++;
                continue;
            }else
            {//0
                WhoInvert.set(i);
                HasAdd=false;
                i++;
                break;
            }
        }else
        {
            //1
            if(WhoInvert.test(i))
            {
                WhoInvert.set(i,0);
                HasAdd=true;
                i++;
                if(i>=WhoInvert.size())
                        Over=true;
                continue;
            }else
            {//0
                WhoInvert.set(i);
                HasAdd=false;
                i++;
                break;
            }
        }
    }
    if(Over)
        std::cout<<"yichu\n";
}
    Result=WhoInvert;
    return Result;
}


//两个数连同符号位相加
std::bitset<n> AddTogether
(int Count/*输入补码的长度,超过将丢弃*/,std::bitset<n> GetOne,std::bitset<n> GetSecond)
{

    //两个数连同符号位相加
    bool HasAdd=false;
    bool Over=false;
    int i=0;
    int j=0;
    std::bitset<n> Result;

    while(i<Count)
    {
        if(!HasAdd)
        {
            //两个都是1
            if(GetSecond.test(i)&&GetOne.test(i))
            {
                Result.set(i,0);
                HasAdd=true;
                i++;
                continue;
            }else   if(!GetSecond.test(i)&&!GetOne.test(i))
            {//两个都是 0
                Result.set(i,0);
                HasAdd=false;
                i++;
                continue;
            }else
            {
                Result.set(i);
                HasAdd=false;
                i++;
                continue;
            }
        }else
        {
            //两个都是1
            if(GetSecond.test(i)&&GetOne.test(i))
            {
                Result.set(i);
                HasAdd=true;
                i++;
                if(i>=GetSecond.size())
                    Over=true;
                continue;
            }else   if(!GetSecond.test(i)&&!GetOne.test(i))
            {//两个都是 0
                Result.set(i);
                HasAdd=false;
                i++;
                continue;
            }else
            {
                Result.set(i,0);
                HasAdd=true;
                i++;
                if(i>=GetSecond.size())
                    Over=true;
                continue;
            }
        }
    }
    if(Over)
        std::cout<<"yichu\n";


    return Result;
}

//减1操作
std::bitset<n> SubOne
(int Count/*要操作的位数*/,std::bitset<n> Source)
{
    std::bitset<n> Result=Source;
    bool JieWei=false;
    bool Over=false;
    int i=0;

    while(i<Count)
    {
        if(!JieWei)
        {
            if(Result.test(i))
            {
                Result.set(i,0);
                JieWei=false;
                i++;
                break;
            }else
            {
                Result.set(i,1);
                JieWei=true;
                 i++;
                continue;
            }
        }else
        {//被借位了
            if(Result.test(i))
            {
                Result.set(i,0);
                JieWei=false;
                 i++;
                break;
            }else
            {
                Result.set(i,1);
                JieWei=true;
                 i++;
                if(i>=Count)
                    Over=true;
                continue;
            }
        }
    }//while

    if(Over)
        std::cout<<"jie wei jie chu jie le\n";
    return Result;
}

std::bitset<n>
AddOne(int Count/*要操作的位数*/,std::bitset<n> Source)
{
    std::bitset<n> Result=Source;
    bool HasAdd=false;
    bool Over=false;
    int i=0;

    while(i<Count)
    {
        if(!HasAdd)
        {
            if(Result.test(i))
            {
                Result.set(i,0);
                HasAdd=true;
                i++;
                continue;
            }else
            {
                Result.set(i,1);
                HasAdd=false;
                 i++;
                break;
            }
        }else
        {//进位了
            if(Result.test(i))
            {
                Result.set(i,0);
                HasAdd=true;
                i++;
                if(i>=Count)
                    Over=true;
                continue;
            }else
            {
                Result.set(i,1);
                HasAdd=false;
                 i++;
                break;
            }
        }
    }//while

    if(Over)
        std::cout<<"jing wei jie chu jie le\n";
    return Result;
}

int main ()
{
    std::string strj1;
    std::string strj2;
    std::string strw1;
    std::string strw2;
    std::bitset<n> b_j1;
    std::bitset<n> b_j2;
    std::bitset<n> b_QiuFu_j2;
    std::bitset<n> b_QiuFu_w2;
    std::bitset<n> b_w1;
    std::bitset<n> b_w2;
    std::bitset<n> b_Save_Outw;//保存右移出的位
    std::bitset<n> b_Temp_j;//b_j1 b_j2 计算结果的中间变量
    std::bitset<n> b_Temp_w;//b_w1 b_w2 计算结果的中间变量
    std::bitset<n> b_Result_j;//结果阶码
    std::bitset<n> b_One;

    int i,j;
    int jCout=0;  //用来判断符号位
    int wCount=0;//输入尾数总的字数个数
    int RightMoveWhichWei=2;//0 w1移  1 w2移  2不移
    int RightMoveBit=0;//右移的位数

    b_One.set(0);//b_One是个常量   最后一个是1   000000****1


     std::cout<<"qin shu ru deng chang de bu ma zuo wei jie ma\n";

    //得到string  补码
    std::cin>>strj1;
    std::cin>>strj2;
    //赋值给bitset
    b_j1=std::bitset<n>(strj1);
    b_j2=std::bitset<n>(strj2);

    //一定要保证输入的两阶码是等长双符号位
    jCout=strj1.size();
  //  std::cout<<jCout;

    //都存在1 即0操作数检查
    if(b_j1.any()&&b_j2.any())
        std::cout<<"b_j1 any  && b_j2 any\n";
对阶//
    //对阶
    //计算相差
    //因为输入的要求是双符号等长补码
    //所以直接对第二个数连同符号位取反加1

    //取反加1
    b_QiuFu_j2=Invert(jCout,b_j2,true);

    std::cout<<"b_QiuFu_j2:\t\t\t"<<b_QiuFu_j2<<"\n";
    std::cout<<"b_j1:\t\t\t\t"<<b_j1<<"\n";
    //相加 得出双符号位阶差  只加到符号位最高位,超过将丢弃
    b_Temp_j=AddTogether(jCout,b_j1,b_QiuFu_j2);

    std::cout<<"b_Temp_j:\t\t\t"<<b_Temp_j<<"\n";
    //判断有没溢出
    if(b_Temp_j.test(jCout-1)&&b_Temp_j.test(jCout-2))
        std::cout<<"mei you yi chu\n";
    else if (!b_Temp_j.test(jCout-1)&&!b_Temp_j.test(jCout-2))
        std::cout<<"mei you yi chu\n";
    else
    {
            std::cout<<"yi chu le\n";
            getch();
            getch();
            return 0;
    }

    /这里溢出了的话,下面就进行不了了


    //阶码是负的 //除符号位  先减1再取反
    //这里得到了尾数要右移的位数
    if(b_Temp_j.test(jCout-1)&&b_Temp_j.test(jCout-2))
    {//阶码是负数
        //除符号位  先减1再取反
        b_Temp_j[jCout-1]=0;
        b_Temp_j[jCout-2]=0;
        b_Temp_j=SubOne(jCout,b_Temp_j);
        b_Temp_j=Invert(jCout-2,b_Temp_j,false);
        RightMoveWhichWei=0;//第一个尾数将右移
    }else if(!b_Temp_j.test(jCout-1)&&!b_Temp_j.test(jCout-2)&&b_Temp_j.to_ulong())
    {
         RightMoveWhichWei=1;//第二个尾数将右移
    }

    std::cout<<"b_Temp_j:\t\t\t"<<b_Temp_j<<"\n";
    RightMoveBit=b_Temp_j.to_ulong();
    std::cout<<"RightMoveBit:\t\t\t"<<RightMoveBit<<"\n";

 尾数求和求差///

    //要求双符号位等长尾数
    //得到string
     std::cout<<"qin shu ru deng chang de bu ma zuo wei Wei shu\n";
    std::cin>>strw1;
    std::cin>>strw2;
    //赋值给bitset
    b_w1=std::bitset<n>(strw1);
    b_w2=std::bitset<n>(strw2);

    wCount=strw1.size();
    std::cout<<"\nwCount\t\t\t"<<wCount<<"\n";

    if(0==RightMoveWhichWei)
    {   //第一个尾数右移  右移符号位之后的东西           //第一个数的阶码将加1   RightMoveBit次
        for(i=0;i<RightMoveBit;i++)
        {
        std::cout<<"\nb_Onej1 fin\t\t"<<b_j1<<"\n";
        b_j1=AddTogether(jCout,b_j1,b_One);
        std::cout<<"\nb_Onej1 fout\t\t"<<b_j1<<"\n";
        }
        std::cout<<"\nb_Onej1\t\t"<<b_j1<<"\n";
        b_Result_j=b_j1;
        // 保存右移出的位
        b_Save_Outw=SaveRightMoveOutBIt(RightMoveBit,b_w1,0,NULL);
        b_w1=RightMove(RightMoveBit,b_w1);
         std::cout<<"\nb_Save_Outw\t\t"<<b_Save_Outw<<"\n";
         std::cout<<"b_w1\t\t\t"<<b_w1<<"\n";
         std::cout<<"b_w2\t\t\t"<<b_w2<<"\n";
    }else if(1==RightMoveWhichWei)
    {
        //第二个尾数右移   右移符号位之后的东西    //第二个数的阶码将加1   RightMoveBit次
        for(i=0;i<RightMoveBit;i++)
        {
            std::cout<<"\nb_Onej2 fin\t\t"<<b_j2<<"\n";
            b_j2=AddTogether(jCout,b_j2,b_One);
            std::cout<<"\nb_Onej2 fout\t\t"<<b_j2<<"\n";
        }
        std::cout<<"\nb_Onej2\t\t\t"<<b_j2<<"\n";
        b_Result_j=b_j2;
        // 保存右移出的位
        b_Save_Outw=SaveRightMoveOutBIt(RightMoveBit,b_w2,0,NULL);
        b_w2=RightMove(RightMoveBit,b_w2);
        std::cout<<"\n2b_Save_Outw\t\t"<<b_Save_Outw<<"\n";
        std::cout<<"2b_w1\t\t\t"<<b_w1<<"\n";
        std::cout<<"2b_w2\t\t\t"<<b_w2<<"\n";
    }else if(2==RightMoveWhichWei)
    {//尾数即不左移 也不右移  说明阶码一样大
        b_Result_j=b_j1;
    }


# if 1
    //加法
    b_Temp_w=AddTogether(wCount,b_w1,b_w2);
    std::cout<<"b_Temp_w\t\t"<<b_Temp_w<<"\n";
#endif

# if 0
    //减法
    //对第二个数连同符号位取反加1
    //如果是第二个数右移了   因为右移了,所以位数也减了(要用到异或)
    if(1==RightMoveWhichWei)
        b_QiuFu_w2=Invert(wCount-RightMoveBit,b_w2,true);
    else
        b_QiuFu_w2=Invert(wCount,b_w2,true);
    std::cout<<"b_QiuFu_w2\t\t"<<b_QiuFu_w2<<"\n";
    std::cout<<"b_w1\t\t\t"<<b_w1<<"\n";
    b_Temp_w=AddTogether(wCount,b_w1,b_QiuFu_w2);
    std::cout<<"b_Temp_w\t\t"<<b_Temp_w<<"\n";
#endif
/规格化///


    i=wCount;
    j=RightMoveBit;
 while(b_Temp_w[i-1]==b_Temp_w[i-3]&&b_Temp_w[i-1]==b_Temp_w[i-2])
{//左规 符号位与最高数值位不同
        b_Temp_w[i-1]=0;//去除最高位
        b_Temp_w <<= 1;//左移一位
        //阶码减1一次
        b_Result_j=SubOne(jCout,b_Result_j);
        std::cout<<"zuo gui b_Result_j\t\t"<<b_Result_j<<"\n";

        //将前面右移出去的位补回来 如果需要
        if(j>=0)
        {
            b_Temp_w[0]=b_Save_Outw[j-1];
            b_Save_Outw[j-1]=0;  //将补出去的位置0
            b_Save_Outw <<=1;  //左移 即与RightMoveBit对应
            std::cout<<"zuo gui b_Save_Outw\t\t"<<b_Save_Outw<<"\n";
            j--;
        }
        std::cout<<"zuo gui b_Temp_w\t\t"<<b_Temp_w<<"\n";
}//while

 i=wCount;
 while(b_Temp_w[i-1]!=b_Temp_w[i-2])
 {//右规  符号位不同
         // 保存右移出的位
          b_Save_Outw=SaveRightMoveOutBIt(1,b_Temp_w,RightMoveBit,b_Save_Outw);
          RightMoveBit++;
          b_Temp_w >>= 1;//右移一位
          std::cout<<"you gui b_Save_Outw\t\t"<<b_Save_Outw<<"\n";
          std::cout<<"you gui b_Temp_w\t\t"<<b_Temp_w<<"\n";
          //阶码加1一次
          b_Result_j=AddOne(jCout,b_Result_j);
          std::cout<<"you gui b_Result_j\t\t"<<b_Result_j<<"\n";
 }


/舍入处理/
 std::cout<<"\n\nshe rv chu li\t\t\n";
 //0舍1入 尾数加1一次
 if(RightMoveBit!=0)//有右移
 if(b_Save_Outw.test(RightMoveBit-1))//最高位为1
    b_Temp_w=AddOne(wCount,b_Temp_w);

 std::cout<<"b_Temp_w\t\t"<<b_Temp_w<<"\n";

//再规格化
 i=wCount;
 j=RightMoveBit;
while(b_Temp_w[i-1]==b_Temp_w[i-3]&&b_Temp_w[i-1]==b_Temp_w[i-2])
{//左规 符号位与最高数值位不同
     b_Temp_w[i-1]=0;//去除最高位
     b_Temp_w <<= 1;//左移一位
     //阶码减1一次
     b_Result_j=SubOne(jCout,b_Result_j);
     std::cout<<"zuo gui b_Result_j\t\t"<<b_Result_j<<"\n";

     //将前面右移出去的位补回来 如果需要
     if(j>=0)
     {
         b_Temp_w[0]=b_Save_Outw[j-1];
         b_Save_Outw[j-1]=0;  //将补出去的位置0
         b_Save_Outw <<=1;  //左移 即与RightMoveBit对应
         std::cout<<"zuo gui b_Save_Outw\t\t"<<b_Save_Outw<<"\n";
         j--;
     }
     std::cout<<"zuo gui b_Temp_w\t\t"<<b_Temp_w<<"\n";
}//while

i=wCount;
while(b_Temp_w[i-1]!=b_Temp_w[i-2])
{//右规  符号位不同
      // 保存右移出的位
       b_Save_Outw=SaveRightMoveOutBIt(1,b_Temp_w,RightMoveBit,b_Save_Outw);
       RightMoveBit++;
       b_Temp_w >>= 1;//右移一位
       std::cout<<"you gui b_Save_Outw\t\t"<<b_Save_Outw<<"\n";
       std::cout<<"you gui b_Temp_w\t\t"<<b_Temp_w<<"\n";
       //阶码加1一次
       b_Result_j=AddOne(jCout,b_Result_j);
       std::cout<<"you gui b_Result_j\t\t"<<b_Result_j<<"\n";
}



 /判溢出/
  std::cout<<"\n\npang duan yi chu\t\t\n";
if((0==b_Result_j[jCout-1]&&0==b_Result_j[jCout-2])
        ||(1==b_Result_j[jCout-1]&&1==b_Result_j[jCout-2]))
{
    //没有溢出
    std::cout<<"RightMoveBit\t\t"<<RightMoveBit<<"\n";
     std::cout<<"b_Save_Outw\t\t"<<b_Save_Outw<<"\n";
     std::cout<<"b_Temp_w\t\t"<<b_Temp_w<<"\n";
     std::cout<<"b_Result_j\t\t"<<b_Result_j<<"\n";

}else if(0==b_Result_j[jCout-1]&&1==b_Result_j[jCout-2])
{
    //上溢
     std::cout<<"上溢\t\t\n";


}else if(1==b_Result_j[jCout-1]&&0==b_Result_j[jCout-2])
{
    //下溢
    b_Temp_w.reset();
    b_Result_j.reset();
    std::cout<<"b_Temp_w\t\t"<<b_Temp_w<<"\n";
    std::cout<<"b_Result_j\t\t"<<b_Result_j<<"\n";
}


    getch();
    getch();
    return 0;
}






















评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值