C++实现大数据的加法、减法和乘法

最近在做大数据的四则运算,为了加强自己的记忆,所以就写了这样一篇博客。这里只有加法、减法和乘法的,除法的暂时未实现,以后实现了我会发上来的。

首先,什么叫做大数据,大数据在我看来就是那些用一般的基本类型无法表示的数据(超出了范围)。我们做这个大数据的四则运算首先得获取到这些数据,既然一般的数据类型无法表示这些数据,那我们就用数组来表示,因为数组按照理论来说是可以“无限”的。为了接收方便,我们使用char型数组来接收数据,但是在我们运算的时候,我们应该把他转换成int型数组,这样便于计算和判断数组的进位,这个在后面会提到。

一般来说,如果数据里面没有小数点的话,那么数据的运算会比较简单,这里我写的程序是考虑到了小数点的问题的,所以,我们首先要处理小数点的问题。

char a[MAX],b[MAX];
int arr_1[MAX]={0},arr_2[MAX]={0};
int length_1,length_2;
int pos_1,pos_2; //记录小数点的位置,同时代表整型数据的长度
int i = 0;
pos_1 = -1;
pos_2 = -1;
gets(a);
gets(b);
length_1 = strlen(a);
length_2 = strlen(b);
while(a[i] != '\0')
{
if (a[i] == '.')
pos_1 = i;
arr_1[i] = a[i] - '0';
i++;
}
i = 0;
while(b[i] != '\0')
{
if (b[i] == '.')
pos_2 = i;
arr_2[i] = b[i] - '0';
i++;
}

//数据没有小数点的时候,pos等于数组的长度
if (pos_1 < 0)
pos_1 = length_1;
if (pos_2 < 0)
pos_2 = length_2;

这里我们接受了数据,并且把它转换成了整型数组,而且为了便于以后的计算 ,我们记录了小数点的位置,当数据没有小数点的时候我们让pos等于数据的长度。

这里的运算我是模拟手算来实现的,比如说加法,我们要把两个数组代表的位数对好,所以pos是极其重要的。

因为是模拟手算,所以我们要写一个进位的函数来判断那一位是否大于或等于10.

void carry(int length,int pos)
{
int temp;
for (int k = length; k >= 0; k--)
{
if (sum[k] >= 10)
{
temp = sum[k] / 10;
sum[k] = sum[k] % 10;
if (k == 0)
{
for (int i = length; i >= 0; i--)
{
sum[i+1] = sum[i];
}
sum[k] = temp;
length++;
pos++;
}
else
sum[k-1] += temp;
}
}


for (int i = 0; i < length; i++)
{
if (i == pos)
cout<<'.';
cout<<sum[i];
}
}

我使用了一个sum数组来保存俩个数据运算的最终结果,因为我是在数据进行运算的时候不管小数点的,所以在sum里面是没有小数点的,sum数组是全局变量,我只记住了小数点的位置,输出到小数点位置的时候我再输出小数点。

void numAdd(int arr_1[],int length_1,int pos_1,int arr_2[],int length_2,int pos_2)
{
int num = 0; //两个小数点位置之间的差值,方便模拟手算
int length = 0; //sum整型长度
int length_float_1,length_float_2; //这里代表着浮点型数据的长度
int pos;
length_float_1 = length_1 - pos_1 -1;
length_float_2 = length_2 - pos_2 -1;
/*将数组通过小数点小标的方法来实现整型和小数位的隔离相加*/
if (pos_1 >= pos_2)
{
num = pos_1 - pos_2;
for (int i = 0; i < pos_2; i++)
arr_1[i+num] += arr_2[i];
for (length = 0; length < pos_1; length++) //将长的那一组给sum
sum[length] = arr_1[length];

else
{
num = pos_2 - pos_1;
for (int i = 0; i < pos_1; i++)
arr_2[i+num] += arr_1[i];
for (length = 0; length < pos_2; length++)
sum[length] = arr_2[length];
}
pos = length;
/*小数位的相加*/
if (length_float_1 < 0 || length_float_2 < 0)
{
if (length_float_1 < 0 && length_float_2 >= 0)
{
for (int i = 0; i < length_float_2; i++)
{
sum[pos+i] = arr_2[i+pos_2+1];
length++;
}
}
else if (length_float_2 < 0 && length_float_1 >= 0)
{
for (int i = 0; i < length_float_1; i++)
{
sum[pos+i] = arr_1[i+pos_1+1];
length++;
}
}
}
else
{
if (length_float_1 >= length_float_2)
{
for (int i = 0; i < length_float_2; i++)
arr_1[i+pos_1+1] += arr_2[i+pos_2+1];
for (int i = 0; i < length_float_1; i++)
{
sum[pos+i] = arr_1[i+pos_1+1];
length++;
}
}
else
{
for (int i = 0; i < length_float_1; i++)
arr_2[i+pos_2+1] += arr_1[i+pos_1+1];
for (int i = 0; i < length_float_2; i++)
{
sum[pos+i] = arr_2[i+pos_2+1];
length++;
}
}
}
carry(length,pos);
}

这里加法和减法我都是分为整型部分和非整型部分,这里pos的作用就体现出来了。通过num的值来对好数组元素代表数据的位数,运算完成后把sum的长度和小数点的位置传到进位函数里面去,因为sum是全局变量所以可以不用将它传进去。

void subduction(int arr_1[],int length_1,int pos_1,int arr_2[],int length_2,int pos_2)
{
int num = 0;
int length = 0;
int bigFloat; //bigFloat保存最大的浮点长度
int length_float_1,length_float_2; //这里代表着浮点型数据的长度
int pos;
length_float_1 = length_1 - pos_1 -1;
length_float_2 = length_2 - pos_2 -1;
bigFloat = length_float_1 > length_float_2 ?length_float_1:length_float_2;
if (pos_1 >= pos_2)
{
num = pos_1 - pos_2;
for (int i =length_2-1; i >= 0; i--)
{
if (i == pos_2)
continue;
arr_1[i+num] -= arr_2[i];
if (arr_1[i+num] < 0 && (i+num) != 0)
{
arr_1[i+num] += 10;
if (i-1 == pos_2)
arr_1[i+num-2]--;
else
arr_1[i+num-1]--;
}
}
if (length_float_1 < 0)
{
if (length_float_2 < 0)
{
length = length_1;
pos = pos_1;
}
else
{
length = length_1 + length_float_2;
pos = pos_1;
}
}
else
{
pos = pos_1;
length = pos_1 + bigFloat;
}
for (int i = 0; i < length; i++)
{
if (i >= pos_1)
sum[i] = arr_1[i+1];
else
sum[i] = arr_1[i];
}
}
else
{
num = pos_2 - pos_1;
for (int i =length_1-1; i >= 0; i--)
{
if (i == pos_1)
continue;
arr_2[i+num] -= arr_1[i];
if (arr_2[i+num] < 0 && (i+num) != 0)
{
arr_2[i+num] += 10;
if (i-1 == pos_1)
arr_2[i+num-2]--;
else
arr_2[i+num-1]--;
}
}
if (length_float_2 < 0)
{
if (length_float_1 < 0)
{
length = length_2;
pos = pos_2;
}
else
{
length = length_2 + length_float_1;
pos = pos_2;
}
}
else
{
pos = pos_2;
length = pos_2 + bigFloat;
}
for (int i = 0; i < length; i++)
{
if (i >= pos_2)
sum[i] = arr_2[i+1];
else
sum[i] = arr_2[i];
}
cout<<'-';
}
carry(length,pos);
}

减法和加法类似,同样是分为两部分,两个部分的较长的给sum,最后判断进位。

void multiplication(int arr_1[],int length_1,int pos_1,int arr_2[],int length_2,int pos_2)
{
int length = 0;
int pos = 0;
int length_float_1,length_float_2; //这里代表着浮点型数据的长度
length_float_1 = length_1 - pos_1 -1;
length_float_2 = length_2 - pos_2 -1;
/*将有小数位的数变成无小数位的*/
if (length_float_1 >= 0)
{
for (int i = 0; i < length_float_1; i++)
{
arr_1[i+pos_1] = arr_1[i+pos_1+1];
}
length_1 -= length_float_1;
}
else
length_float_1 = 0;
if (length_float_2 >= 0)
{
for (int i = 0; i < length_float_2; i++)
{
arr_2[i+pos_2] = arr_2[i+pos_2+1];
}
length_2 -= length_float_2;
}
else
length_float_2 = 0;
for (int i = 0; i < length_1; i++)
{
for (int j = 0; j < length_2; j++)
{
sum[i+j] += (arr_1[i] * arr_2[j]);
}
}
length = length_1 + length_2 - 1;
pos = length - (length_float_1 + length_float_2);
carry(length,pos);
}

乘法的话和加法就有些不同。因为乘法的手算是这个数里面的一位数与另一个数的全部位数一个个相乘,这里我们可以注意它的数组的小标的变化sum[i+j] += (arr_1[i] * arr_2[j]);两个嵌套for循环很好解决了下标的问题,你们可以去写一些数据来试试,sum 的下标就会等两个下标的相加。如果没有小数点的话,我们直接使用两个循环来做 ,直接结果就出来了,但是这里要考虑到小数点的问题,所以我们就先对数据进行去小数点,我们只需要记录小数点的个数,将两个小数点的个数相加就是最后结果的小数点的个数了。

没有写过博客,并且自己的功底不是很好,写的不好的地方欢迎大家来批评。大家有什么更好的办法也可以告诉我,共同学习和进步。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值