在ACM的题目中经常会遇到大数相加和相乘的问题,在有些公司的面试题中也有暗含要用大数才能解决的问题。比如:输入三个整数,写一个程序判断这个三个整数能否构成一个直角三角形。此题算法很简单,但是却暗含着结果可能溢出的问题。如果不会用大数,此题就无法给出完美的答案。
下面给出大数的乘法和加法算法:
1、加法:
//
assume m is bigger than n.
char * add( char * a, char * b, int m, int n)
{
// 为结果分配内存空间。
char * c = ( char * )malloc((m + 2 ) * sizeof ( char ));
memset(c, 0 , (m + 2 ) * sizeof ( char ));
// 将字符(0 + 0x30 到 9 + 0x30)转换为数字(0到9)进行计算。
for ( int i = m, j = n - 1 ; j >= 0 ; -- i, -- j)
c[i] += (b[j] - 0x30 );
for ( int i = m, j = m - 1 ; j >= 0 ; -- i, -- j)
{
c[i] += (a[j] - 0x30 );
if (c[i] > 9 )
{
c[i - 1 ] += 1 ;
c[i] -= 10 ;
}
}
// 将由纯数字组成的结果转换为字符串,并去除首部可能还存在的零。
char * add( char * a, char * b, int m, int n)
{
// 为结果分配内存空间。
char * c = ( char * )malloc((m + 2 ) * sizeof ( char ));
memset(c, 0 , (m + 2 ) * sizeof ( char ));
// 将字符(0 + 0x30 到 9 + 0x30)转换为数字(0到9)进行计算。
for ( int i = m, j = n - 1 ; j >= 0 ; -- i, -- j)
c[i] += (b[j] - 0x30 );
for ( int i = m, j = m - 1 ; j >= 0 ; -- i, -- j)
{
c[i] += (a[j] - 0x30 );
if (c[i] > 9 )
{
c[i - 1 ] += 1 ;
c[i] -= 10 ;
}
}
// 将由纯数字组成的结果转换为字符串,并去除首部可能还存在的零。
c[m + 1] = '/0';
for ( int i = 0 ; i != m + 1 ; ++ i)
c[i] += 0x30 ;
if (c[ 0 ] == 0x30 )
for ( int i = 0 ; c[i] != '/0'; ++ i)
c[i] = c[i + 1 ];
// 返回结果所在内存单元的首地址。
return c;
}
for ( int i = 0 ; i != m + 1 ; ++ i)
c[i] += 0x30 ;
if (c[ 0 ] == 0x30 )
for ( int i = 0 ; c[i] != '/0'; ++ i)
c[i] = c[i + 1 ];
// 返回结果所在内存单元的首地址。
return c;
}
2、乘法:
//
assume m is bigger than n.
char * mult( char * a, char * b, int m, int n)
{
// 为结果分配内存空间。
char * c = ( char * )malloc((m + n + 1 ) * sizeof ( char ));
memset(c, 0 , (m + n + 1 ) * sizeof ( char ));
// 将字符(0 + 0x30 到 9 + 0x30)转换为数字(0到9)进行计算。
for ( int i = m - 1 , r = m + n - 1 ; i >= 0 ; -- i, -- r)
{
for ( int j = n - 1 , k = r; j >= 0 ; -- j, -- k)
{
c[k] += (a[i] - 0x30 ) * (b[j] - 0x30 );
int tmp = c[k] / 10 ;
if (tmp > 1 )
{
c[k - 1 ] += tmp;
c[k] -= tmp * 10 ;
}
}
}
// 将由纯数字组成的结果转换为字符串,并去除首部可能还存在的零。
c[m + n] = '/0';
for ( int i = 0 ; i != m + n; ++ i)
c[i] += 0x30 ;
char * mult( char * a, char * b, int m, int n)
{
// 为结果分配内存空间。
char * c = ( char * )malloc((m + n + 1 ) * sizeof ( char ));
memset(c, 0 , (m + n + 1 ) * sizeof ( char ));
// 将字符(0 + 0x30 到 9 + 0x30)转换为数字(0到9)进行计算。
for ( int i = m - 1 , r = m + n - 1 ; i >= 0 ; -- i, -- r)
{
for ( int j = n - 1 , k = r; j >= 0 ; -- j, -- k)
{
c[k] += (a[i] - 0x30 ) * (b[j] - 0x30 );
int tmp = c[k] / 10 ;
if (tmp > 1 )
{
c[k - 1 ] += tmp;
c[k] -= tmp * 10 ;
}
}
}
// 将由纯数字组成的结果转换为字符串,并去除首部可能还存在的零。
c[m + n] = '/0';
for ( int i = 0 ; i != m + n; ++ i)
c[i] += 0x30 ;
if
(c[
0
]
==
0x30
)
for ( int i = 0 ; c[i] != '/0'; ++ i)
c[i] = c[i + 1 ];
// 返回结果所在内存单元的首地址。
return c;
}
for ( int i = 0 ; c[i] != '/0'; ++ i)
c[i] = c[i + 1 ];
// 返回结果所在内存单元的首地址。
return c;
}