/* 功能: 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; }

|