任意进制相互转换
写bug有很长时间了,还记得最开始接触的就是10进制转换成多进制的项目,那时刚入坑,用了一系列不忍直视的代码,现在回想起来酸爽十足。
最近有接触到一个项目了,又是多进制转换的,回去翻看了下自己之前写的代码,臃肿繁琐,看到一半就不想用了,于是就自己重新写了,这回感觉精简了不少,也就好意思拿出来分享咯。
/// <summary>
/// 十进制数转成任意进制.
/// </summary>
/// <param name="input">输入十进制的数.</param>
/// <param name="nLen">指定输出字符串长度.</param>
/// <param name="sTemplate">多进制的模板字符串,可以确定多少进制.</param>
/// <returns>
CString IntFormatAnySys(const int input, const int nLen, const CString sTemplate)
{
int nbit = sTemplate.GetLength();
int tempipnut = input;
CString strText = _T("");
int nHigh, nLow;
bool bInsertNull = false;
for (;;) {
if (!bInsertNull) {
// 高位数
nHigh = tempipnut/ nbit;
// 低位数
nLow = tempipnut % nbit;
strText.Insert(0, sTemplate[nLow]);
tempipnut = nHigh;
}
else {
strText.Insert(0, sTemplate[0]);
}
if (nHigh <= 0) {
if (strText.GetLength() < nLen) {
bInsertNull = true;
continue;
}
break;
}
}
return strText;
}
// 使用例子,以下将十进制124,转换成4位16进制数,结果是:007C
// sTemplate可以是任意进制,如34进制,36进制等,把需要的进制的字符
// 顺序依次输入进去就可以了。
CString sRet=IntFormatAnySys(124,4,_T("0123456789ABCDEF"));
至于任意进制转换成十进制的数,我这里有个方案,还是有点bug,不适合超大数据的转换。
/// <summary>
/// 任何进制转换成十进制的数
/// </summary>
/// <param name="s">需要转换的进制字符串.</param>
/// <param name="sTemplate">进制字符串模板.</param>
/// <returns>
int AnySysToInt(const CString s, const CString sTemplate)
{
int nValue = 0;
for (int i = s.GetLength() - 1, n = 0; i >= 0; i--, n++) {
int nPos = sTemplate.Find(s[i]);
// 最大进制
long nMaxRate = sTemplate.GetLength();
nPos *= pow(nMaxRate, n);
nValue += nPos;
}
return nValue;
}
// 使用例子:以下将8进制1254,转换成10进制数,结果是:648。
int nRet = AnySysToInt(_T("1254"), _T("01234567"));