n进制补码,格雷码

/*
 功能:
    1.  任意进制到十进制(其他任意进制认为是补码,即左起首位如果为1则被认为是补码)
    2.  十进制到任意进制(负数则输出其补码形式)
    3.  得到十进制数的Gray码
    4.  得到Gray码对应的二进制编码

    时间: 2002-7-3
    注意: 当其他进制的进制数超过10时,使用A-Z这26个字母代替10-35这26个数.
       所以实际上程序可以接受的输入在35(字母Z)以下.
*/

#include <iostream>
#include <sstream>

using namespace std;

//任意进制到十进制
bool Other2Dec(int &nDec , int nOther, int nBase );
bool Other2Dec(int &nDec , string strOther, int nBase );
//十进制到任意进制(负数采用补码形式)
bool Dec2Other(string &strOther,int nDec, int nBase);
//得到十进制数的Gray码
bool GetGrayCode(string &strGrayCode , int nDec);
//得到Gray码对应的二进制编码
bool GetBinCodeByGrayCode(string &strBinCode, const string &strGrayCode);

const int cnMinDecNum = static_cast<int>('0');
const int cnMaxDecNum = static_cast<int>('9');
const int cnMinHexNum = static_cast<int>('A');
const int cnMaxHexNum = static_cast<int>('Z');

void main()
{
 //以下为测试代码:
  
 int nDec ;
 int nBase;
 string strOther;
 string strGrayCode;
 string strBinCode;
 cout<<"十进制/t格雷码/t格雷码->二进制/t十进制->二进制/t二进制->十进制"<<endl;
 for(int i=-9;i<=0;i++)
 {
  GetGrayCode(strGrayCode,i);
  GetBinCodeByGrayCode(strBinCode,strGrayCode);
  Dec2Other(strOther,i,2);
  Other2Dec(nDec,strOther,2);
  cout<<i    //十进制
   <<"/t"<<strGrayCode //格雷码
   <<"/t/t"<<strBinCode  //格雷码->二进制
   <<"/t"<<strOther //十进制->二进制
   <<"/t/t"<<nDec  //二进制->十进制
   <<endl;
 }
 
 char ch;
 cout<<"是否继续(y/n)?";
 cin >> ch;
 if (ch != 'y'  && ch != 'Y')
  goto ExitFunc;

 cout <<"十进制转换到其他进制:"<<endl;
 cout<<"输入要被转换的十进制的数和希望的进制数(base):";
 cin>>nDec>>  nBase;
 Dec2Other(strOther,nDec,nBase);
 cout<<"十进制数" <<nDec<<"转化为"<<nBase<<"进制数为"<<strOther<<endl<<endl;
 
 cout<<"是否继续(y/n)?";
 cin >> ch;
 if (ch != 'y'  && ch != 'Y')
  goto ExitFunc;

 cout<<"其他进制数转换到十进制数:"<<endl;
 cout<<"输入要被转换的其他进制的数和进制数(base):";
 cin>> strOther>> nBase;
 if (Other2Dec(nDec , strOther,nBase))
  cout <<nBase<<"进制数转换到十进制数为"<<nDec<<endl;
 else
  cout <<"转换失败!"<<endl;

ExitFunc: 
 cout<<"按任意键退出..."<<endl;
 cin.get();
}

//----------------Other2Dec---------------
//功能:将其他进制的数转化为十进制
//参数:
// nDec  : 返回的十进制数
// nOther: 其他进制数的值
// nBase : 其他进制数的进制
//返回值:
// true  : 输入合法,操作成功
//  false : 输入不合法,操作失败
bool Other2Dec(int &nDec, int nOther, int nBase =2 )
{
 ostringstream   ostrOther;
 ostrOther << nOther;
 string strOther;
 strOther = ostrOther.str();

 return Other2Dec(nDec, strOther,nBase);
}


//----------------Other2Dec---------------
//功能:将其他进制的数转化为十进制
//参数:
// nDec  : 返回的十进制数
// nOther: 其他进制数的值
// nBase : 其他进制数的进制
//返回值:
// true  : 输入合法,操作成功
//  false : 输入不合法,操作失败
bool Other2Dec(int &nDec, string strOther, int nBase =2 )
{
 int nLen = strOther.length();
 if(nLen <=0)
  return false;
 if(nBase <=1 || nBase >=36)
 {
  cout<<"错误的进制的值,请输入2-35!"<<endl;
  return false;
 } 
 //补齐4的整数倍位数
 while( strOther.length() % 4 != 0)
 {
  strOther = "0" + strOther;
 }

 nDec =0;
 for(int i=0;i<nLen;i++)
 {
  char ch = strOther.at(i);
  int nCh = static_cast<int>(ch);
  if(nBase < 10)
  {
   if(nCh>= cnMinDecNum && nCh <= cnMaxDecNum)
    nCh = nCh - cnMinDecNum + 0;
   else
   {
    cout<<"---非法的输入!---"<<endl;
    return false;
   }
  }
  else
  {
   if( nCh >= cnMinHexNum  && nCh <= cnMaxHexNum)
    nCh = nCh - cnMinHexNum + 10; 
   else if(nCh>= cnMinDecNum && nCh <= cnMaxDecNum)
    nCh = nCh - cnMinDecNum + 0 ;
   else
   {
    cout<<"---非法的输入!---"<<endl;
    return false;
   }
  }
  nDec = nDec * nBase + nCh;
 } 
 //如果以1开头,则表示是负数,由补码的定义,需要使用 nDec = -1 * (pow(2,n) - nDec);
 if(strOther.at(0) == '1')
 {
  int nNum =1;
  for(int j=0;j<strOther.length();j++)
  {
   nNum *= nBase;
  }
  nDec = -1 * (nNum - nDec);
 }
 return true;
}


//----------------Dec2Other---------------
//功能:将十进制数转化为其他进制的数
//参数:
// strOther  : 返回的其他进制数字符串
// nDec  : 其他进制数的值
// nBase : 其他进制数的进制
//返回值:
// true  : 输入合法,操作成功
//  false : 输入不合法,操作失败
bool Dec2Other(string &strOther,int nDec, int nBase =2)
{
 if(nBase <=1 || nBase >=36)
 {
  cout<<"错误的进制的值,请输入2-35!"<<endl;
  return false;
 }

 //当小于0时,下面将nDec用补码表示,
 //即将nDec 变为:  nDec = pow(2,n) + nDec; 
 //其中n为编码的维数,即nDec表示为有符号其它进制数时所需要的位数.
 if (nDec < 0)   
 {
  int nNum = nDec * -1;
  int nDigit =0;
  while(nNum >0)
  {
   nNum = nNum / nBase;
   nDigit++;
  }
  int nDiv = nDigit / 4;
  nDigit = (nDiv + 1) * 4;

  nNum =1;
  for(int i=0;i<nDigit;i++)
  {
   nNum *= nBase;
  }
  nDec = nNum + nDec;
 }

 ostringstream ostrOther;
 int nResidual; //余数
 do
 {
  nResidual = nDec % nBase;
  nDec = nDec / nBase;
  if(nBase >10 && nResidual >=10) //当进制大于10且余数大于10时
  {
   //使之输出A-Z的字母
   nResidual = nResidual - 10 + cnMinHexNum;
   char ch   = static_cast<char>(nResidual);
   ostrOther << ch;
  }else{  //其余情况存入余数
   ostrOther << nResidual ;
  }
 }while(nDec>0);
 string strReverse = ostrOther.str();
 //反转字符串,得到strOther
 strOther = "";
 for(int i=0;i<strReverse.length();i++)
  strOther = strReverse.at(i) + strOther;
 //补齐4的整数倍位数
 while( strOther.length() % 4 != 0)
 {
  strOther = "0" + strOther;
 }
 return true;
}

//----------------GetGrayCode---------------
//功能: 得到十进制数的Gray码
//参数:
//   strGrayCode : 得到的Gray码字符串
//   nDec : 要转换的十进制数
//返回值:
//   true  : 输入合法,操作成功
//   false : 输入不合法,操作失败
//说明:
//   Gray码:  G(i) 和 R(i)分别代表任意一位的格雷码和二进制数,则格雷码构成如下:
//      G(4) = R(4)  
//      G(i) = R(i+1) XOR R(i)   
bool GetGrayCode(string &strGrayCode , int nDec)
{
 string strBin ;
 Dec2Other(strBin,nDec,2);

 ostringstream ostrGrayCode;
 int nCur;
 //左起第一个字符相同
 //减去'0'对应的的整数值,得到真正代表的数字
 int nFro = static_cast<int>(strBin.at(0)) - cnMinDecNum; 
 ostrGrayCode << nFro;

 for(int i=1;i<strBin.length();i++)
 {
   //减去'0'对应的的整数值,得到真正代表的数字
  nFro = static_cast<int>(strBin.at(i-1)) - cnMinDecNum; 
    //减去'0'对应的的整数值,得到真正代表的数字
  nCur = static_cast<int>(strBin.at(i)  ) - cnMinDecNum; 
  ostrGrayCode << ((nFro + nCur ) % 2); //按位异或
 }
 strGrayCode = ostrGrayCode.str();
 return true;
}

//----------------GetBinCodeByGrayCode---------------
//功能: 得到Gray码对应的二进制编码
//参数:
//   strBinCode  : 得到的BCD编码字符串
//   strGrayCode : Gray码字符串
//返回值:
//   true  : 输入合法,操作成功
//   false : 输入不合法,操作失败
bool GetBinCodeByGrayCode(string &strBinCode, const string &strGrayCode)
{
 ostringstream ostrBinCode;
 int nCur;
  //左起第一个字符相同
  //减去'0'对应的的整数值,得到真正代表的数字
 int nFro = static_cast<int>(strGrayCode.at(0)) - cnMinDecNum; 
 ostrBinCode << nFro;
 strBinCode = ostrBinCode.str();
 
 for(int i=1;i<strGrayCode.length();i++)
 {
  //减去'0'对应的的整数值,得到真正代表的数字
  nFro = static_cast<int>(strBinCode.at(i-1)) - cnMinDecNum; 
  //减去'0'对应的的整数值,得到真正代表的数字
  nCur = static_cast<int>(strGrayCode.at(i) ) - cnMinDecNum; 
  ostrBinCode << ((nFro + nCur) % 2 ); //按位异或
  strBinCode = ostrBinCode.str();
 }
 return true;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值