C语言程序设计-大数运算
合集下载
相关主题
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
{
res[index] = s1[index] + s2[index] + delta;
delta = res[index] / 10000;
res[index] %= 10000;
}
if(delta) res[index++] = delta; //如果最后还有进位则数位+1并且进位作为最高位
return index; //返回结果的长度
len0 = add(shu1, len1, shu2, len2, res);
isneg0 = isneg1;
}
else{ //异号时则看作减法
if(sub(shu1, len1, shu2, len2, res, &len0)) //如果num1的数值大
isneg0 = isneg1; //则最终结果的符号跟随num1
for(index = 0; index < len; index++)
{
res[index] = up[index] - delta - dn[index];
if(res[index] < 0) { //发生借位
res[index] += 10000;
delta = 1;
}else
delta = 0;
len2 = get_shu(point + 1, shu2); //将第二个字符串中的数获取到num2中
if(shu1[len1 - 1] < 0){ //如果第一个字符串最高为位负
shu1[len1 - 1] = -shu1[len1 - 1]; //!则转变为正
isneg1 = 1; //并且将负标记设为1
memset(shu1, 0, sizeof(shu1)); //讲两个数串清零这一步十分重要
memset(shu2, 0, sizeof(shu2)); //因为对于长度不等的数串做运算的时候我们都是将短的数串后面当作0看待的
len1 = get_shu(enter, shu1); //将第一个字符串中的数获取到num1中
}
while(index > 1 && res[index - 1] == 0) //消去前导0但至少保留1位
index--;
*len0 = index; //讲长度赋值给主函数中的len0
return up == s1; //如果s1的值大则返回真否则返回假在主函数中用来判断结果的符号
}
int main()
if(point == NULL) break; //如果没有找到','则说明到尽头脱离循环
*point = ' '; //找到','后将其转变为' '空格
sscanf(point, "%d", &shu[index++]); //从空格处向后获取数字到num[]中
}
int i, temp; //index记录数组中数的个数将数组反转高位在后低位在前
if(enter[0] == '\0')break; //如果为空字符串则退出循环
char* point = strchr(enter, '!'); //定义一个字符指针从enter中找'!'字符作为分界线
*point = '\0'; //在找到的';'字符转变为字符串结尾标志这样把enter划分为两个字符串一个以enter打头一个以point+1
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#define MAXN 1010
/*
将满足XX,XXXX,XXXX格式的字符串s转换为数字串存储在数组shu中
*/
int get_shu(char *s, int shu[])
{
int index = 0;
}else
isneg1 = 0; //否则设为0
if(shu2[len2 - 1] < 0){ //同理
isnபைடு நூலகம்g2 = 1;
shu2[len2 - 1] = -shu2[len2 - 1];
}else /*!我们将数串都看作正的并且标记其正负这样利于运算*/
isneg2 = 0;
if(isneg2 == isneg1){ //同号时则看作加法
char* point;
sscanf(s, "%d", &shu[index++]); //从s中获取第一个数到num[]中
for(;;){ //先找','如果找到了将该位置的字符转变为' '空格后再从这个位置读取数字
point = strchr(s, ','); //从s中找到第一个','将其地址存在point中
if(isneg0 && res[index]) printf("-"); //有一种情况除外就是仅有1位且为0这时候不输出'-'号
printf("%d", res[index]);
}else
printf(",%04d", res[index]); //其他数保留前导零4位输出
printf("\n");
else
isneg0 = isneg2; //否则跟随num2
}
int index;
for(index = len0 - 1; index >= 0; index--) //将保存结果的res数串从高到低输出
if(index == len0 - 1){ //如果是最高位则根据标记判断是否输出负号'-'
*/
int add(int *s1, int len1, int *s2, int len2, int *res)
{
int len = (len1 > len2) ? len1: len2; //以两个数串种最长的长度为基准作为运算次数
int index, delta = 0;
for(index = 0; index < len; index++) //从低位到高位进行运算
{
//分别定义了第一个数第二个数和运算结果的数组长度以及正负
int shu1[MAXN], len1, isneg1;
int shu2[MAXN], len2, isneg2;
int res[MAXN], len0, isneg0;
//!enter获取输入的字符串
char enter[MAXN];
while(gets(enter)){ //获取一行
for(i = 0; i < index / 2; i++){
temp = shu[i];
shu[i] = shu[index - i - 1];
shu[index - i - 1] = temp;
}
return index; //返回index的值即数组长度注意长度比下标大1
}
/*
做加法的函数适用于同号的情况
}
/*
做减法的函数适用于异号的情况
*/
int sub(int *s1, int len1, int *s2, int len2, int *res, int *len0)
{
int len, *up, *dn; //len用来记录计算次数up指向绝对值较大的数dn指向绝对值较小的数
while(len1 == len2 && len1 > 1 && s1[len1-1] == s2[len2-1]) //!如果两个数串的长度相同且高位相同则不断向后缩减长度
dn = (up == s1)? s2: s1; //!短的给dn
}else{ //当两数串长度相等的时候
up = (s1[len1-1] > s2[len2-1])? s1: s2; //比较最高位的值大的数给up
dn = (up == s1)? s2: s1;
}
int index, delta = 0; //这里开始从低位向高位计算
}
return 0;
}
{ len1--; len2--; } //因为相同的高位会被抵消但是这个循环至少给两个数串留1位
len = (len1 > len2) ? len1: len2; //取较长的长度作为计算次数
if(len1 != len2) //!当两数串长度不等的时候
{
up = (len1 > len2)? s1: s2; //!长度长的绝对值肯定大赋值给up
res[index] = s1[index] + s2[index] + delta;
delta = res[index] / 10000;
res[index] %= 10000;
}
if(delta) res[index++] = delta; //如果最后还有进位则数位+1并且进位作为最高位
return index; //返回结果的长度
len0 = add(shu1, len1, shu2, len2, res);
isneg0 = isneg1;
}
else{ //异号时则看作减法
if(sub(shu1, len1, shu2, len2, res, &len0)) //如果num1的数值大
isneg0 = isneg1; //则最终结果的符号跟随num1
for(index = 0; index < len; index++)
{
res[index] = up[index] - delta - dn[index];
if(res[index] < 0) { //发生借位
res[index] += 10000;
delta = 1;
}else
delta = 0;
len2 = get_shu(point + 1, shu2); //将第二个字符串中的数获取到num2中
if(shu1[len1 - 1] < 0){ //如果第一个字符串最高为位负
shu1[len1 - 1] = -shu1[len1 - 1]; //!则转变为正
isneg1 = 1; //并且将负标记设为1
memset(shu1, 0, sizeof(shu1)); //讲两个数串清零这一步十分重要
memset(shu2, 0, sizeof(shu2)); //因为对于长度不等的数串做运算的时候我们都是将短的数串后面当作0看待的
len1 = get_shu(enter, shu1); //将第一个字符串中的数获取到num1中
}
while(index > 1 && res[index - 1] == 0) //消去前导0但至少保留1位
index--;
*len0 = index; //讲长度赋值给主函数中的len0
return up == s1; //如果s1的值大则返回真否则返回假在主函数中用来判断结果的符号
}
int main()
if(point == NULL) break; //如果没有找到','则说明到尽头脱离循环
*point = ' '; //找到','后将其转变为' '空格
sscanf(point, "%d", &shu[index++]); //从空格处向后获取数字到num[]中
}
int i, temp; //index记录数组中数的个数将数组反转高位在后低位在前
if(enter[0] == '\0')break; //如果为空字符串则退出循环
char* point = strchr(enter, '!'); //定义一个字符指针从enter中找'!'字符作为分界线
*point = '\0'; //在找到的';'字符转变为字符串结尾标志这样把enter划分为两个字符串一个以enter打头一个以point+1
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#define MAXN 1010
/*
将满足XX,XXXX,XXXX格式的字符串s转换为数字串存储在数组shu中
*/
int get_shu(char *s, int shu[])
{
int index = 0;
}else
isneg1 = 0; //否则设为0
if(shu2[len2 - 1] < 0){ //同理
isnபைடு நூலகம்g2 = 1;
shu2[len2 - 1] = -shu2[len2 - 1];
}else /*!我们将数串都看作正的并且标记其正负这样利于运算*/
isneg2 = 0;
if(isneg2 == isneg1){ //同号时则看作加法
char* point;
sscanf(s, "%d", &shu[index++]); //从s中获取第一个数到num[]中
for(;;){ //先找','如果找到了将该位置的字符转变为' '空格后再从这个位置读取数字
point = strchr(s, ','); //从s中找到第一个','将其地址存在point中
if(isneg0 && res[index]) printf("-"); //有一种情况除外就是仅有1位且为0这时候不输出'-'号
printf("%d", res[index]);
}else
printf(",%04d", res[index]); //其他数保留前导零4位输出
printf("\n");
else
isneg0 = isneg2; //否则跟随num2
}
int index;
for(index = len0 - 1; index >= 0; index--) //将保存结果的res数串从高到低输出
if(index == len0 - 1){ //如果是最高位则根据标记判断是否输出负号'-'
*/
int add(int *s1, int len1, int *s2, int len2, int *res)
{
int len = (len1 > len2) ? len1: len2; //以两个数串种最长的长度为基准作为运算次数
int index, delta = 0;
for(index = 0; index < len; index++) //从低位到高位进行运算
{
//分别定义了第一个数第二个数和运算结果的数组长度以及正负
int shu1[MAXN], len1, isneg1;
int shu2[MAXN], len2, isneg2;
int res[MAXN], len0, isneg0;
//!enter获取输入的字符串
char enter[MAXN];
while(gets(enter)){ //获取一行
for(i = 0; i < index / 2; i++){
temp = shu[i];
shu[i] = shu[index - i - 1];
shu[index - i - 1] = temp;
}
return index; //返回index的值即数组长度注意长度比下标大1
}
/*
做加法的函数适用于同号的情况
}
/*
做减法的函数适用于异号的情况
*/
int sub(int *s1, int len1, int *s2, int len2, int *res, int *len0)
{
int len, *up, *dn; //len用来记录计算次数up指向绝对值较大的数dn指向绝对值较小的数
while(len1 == len2 && len1 > 1 && s1[len1-1] == s2[len2-1]) //!如果两个数串的长度相同且高位相同则不断向后缩减长度
dn = (up == s1)? s2: s1; //!短的给dn
}else{ //当两数串长度相等的时候
up = (s1[len1-1] > s2[len2-1])? s1: s2; //比较最高位的值大的数给up
dn = (up == s1)? s2: s1;
}
int index, delta = 0; //这里开始从低位向高位计算
}
return 0;
}
{ len1--; len2--; } //因为相同的高位会被抵消但是这个循环至少给两个数串留1位
len = (len1 > len2) ? len1: len2; //取较长的长度作为计算次数
if(len1 != len2) //!当两数串长度不等的时候
{
up = (len1 > len2)? s1: s2; //!长度长的绝对值肯定大赋值给up