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;
}
}