typedef unsigned char BYTE;
// BCD 碼串字節序反轉
void ReverseNum(BYTE* num, int cnt);
/*
兩個大的正整數相加之和, 其中:
參數:
num1 整數的BCD碼串1
size1 BCD碼串1的字節數
num2 整數的BCD碼串2
size2 BCD碼串2的字節數
dest 存放結果BCD碼串的緩沖區
size 傳入 dest 緩沖區的尺寸
返回值:
-3 相加失敗, 參數不合法
-2 相加失敗, BCD碼串2存在不合法字符
-1 相加失敗, BCD碼串1存在不合法字符
0 相加失敗, 結果BCD碼串的緩沖區尺寸太小
>0 相加成功, 返回BCD碼串的字節數
*/
int AddBCDInt(const void* num1, int size1, const void* num2, int size2,
void* dest, int size)
{
int result = -3;
int nCnt = 0; // 返回字節數
BYTE btNum1 = 0, btNum2 = 0, btDestNum = 0;
BYTE btHighNum1 = 0, btLowNum1 = 0;
BYTE btHighNum2 = 0, btLowNum2 = 0;
BYTE btHighNum = 0, btLowNum = 0;
BYTE num1Size = 0, num2Size = 0; // 截掉首字節為0后num1,num2的真實size
int maxSize = 0;
BYTE carryFlag = 0; // 進位標記
// 參數合法性判定
if ( num1!=NULL && size1>0 && num2!=NULL && size2>0 && dest!=NULL && size>0 )
{
num1Size = size1;
num2Size = size2;
// 截掉num1\num2為0首字節
for ( int i=0; i<size1; i++ )
{
if ( ((BYTE *)num1)[i] == 0 ) num1Size --;
else break;
}
for ( int i=0; i<size2; i++ )
{
if ( ((BYTE *)num2)[i] == 0 ) num2Size --;
else break;
}
maxSize = (num1Size>num2Size) ? (num1Size+1) : (num2Size+1); // 相加結果最大字節數maxSize
while( maxSize-- > 0 )
{
// num1
if ( size1 > 0 )
{
btNum1 = ( (BYTE *)num1 )[--size1];
btLowNum1 = btNum1 & 0x0F;
btHighNum1 = btNum1 >> 4;
// btNum1高低位合法性驗證
if ( btLowNum1>9 || btHighNum1>9 )
{
result = -1; // 相加失敗, BCD碼串1存在不合法字符
break;
}
}
else
{
btNum1 = 0;
btLowNum1 = 0;
btHighNum1 = 0;
}
// num2
if ( size2 > 0 )
{
btNum2 = ( (BYTE *)num2 )[--size2];
btLowNum2 = btNum2 & 0x0F;
btHighNum2 = btNum2 >> 4;
// btNum2高低位合法性驗證
if ( btLowNum2>9 || btHighNum2>9 )
{
result = -2; // 相加失敗, BCD碼串2存在不合法字符
break;
}
}
else
{
btNum2 = 0;
btLowNum2 = 0;
btHighNum2 = 0;
}
// 字符合法
btLowNum = btLowNum1 + btLowNum2;
btHighNum = btHighNum1 + btHighNum2;
btLowNum += carryFlag; // 進位
if ( btLowNum>9 ) // 進位加6修正
{
btLowNum -= 10;
btHighNum++;
}
// 低位修正結果使高位大於9時,高位進行加6修正
if ( btHighNum > 9 )
{
btHighNum += 6;
carryFlag = 1;
}
else
carryFlag = 0;
btDestNum = (btHighNum << 4) + btLowNum;
if ( btDestNum != 0 || maxSize > 0 )
{
if ( size > nCnt )
{
( (BYTE *)dest )[nCnt++] = btDestNum;
result = nCnt;
}
else
{
result = 0; // 相加失敗, 結果BCD碼串的緩沖區尺寸太小
break;
}
}
}
// BCD 碼串按十進制數的從高到低存放
if ( result > 0 )
{
ReverseNum((BYTE *)dest , nCnt);
}
}
return result;
}
/*
兩個大的正整數相加之和, 其中:
參數:
num 整數的BCD碼串
cnt BCD碼串的字節數
返回值:
無
*/
void ReverseNum(BYTE* num, int cnt)
{
BYTE tmp;
for ( int i = 0; i < (cnt/2); i++ )
{
tmp = num[i];
num[i] = num[cnt-1-i];
num[cnt-1-i] = tmp;
}
}