改正: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;
}
浮点数的加减运算
最新推荐文章于 2024-01-31 16:02:21 发布