⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 大数减法.c

📁 大数加法、减法、乘法和除法的C语言实现源码
💻 C
字号:
/*--------------------------------------------------------------------------
*函数名称: 大数减法
*函数过程:1 比较两个数那一个长
* 2 以长的作为循环次数
* 3 如果两个数长度相等,从最高位开始比直到发现那一个数更大,使大项减去小项
* 4 对应项相减 进位存贮直到下高位相加用
* 5 每一位对应项相减时,处理三种可能的情况,a=b,ab;
* 6 a=b时,则计算,11-12,111-112,要考虑借位
* 7 直到循环结束
*入口参数:numa,numb,result字符串
*出口参数:无
*--------------------------------------------------------------------------*/

void subtract(char *numa, char *numb,char *result)//计算减
            {
            char *pna = findend(numa);//指向numa的一个指针。point numa      pna 指向减数的最低位,
            char *pnb = findend(numb);//指向numb的一个指针                 //pnb 指向被减数的最低位,
            int  along=(int)strlen(numa);//标记数字a的长度;
            int  blong=(int)strlen(numb);//标记数字b的长度;
            int  times = 0;         // 标记要计算多少次。
            int  carry=0;           //存贮借位
            int  clear0=0;          //消除结果最前面无用的'0'  13-5 = 08 的效果!!
            int  isnegative=0;      //用来加上被减数大于减数时补上最后一个负号
            Node *head,   // 用于存贮头指针
            *pstart,  // 用于存贮计算时的首指针
            *pnew;    //作于申请新结点
            head = pstart =new Node;//初始化首结点和头结点。
            pstart -> data = 0;
            pstart -> next = NULL;
            pstart -> ahead = NULL;
            if (abigerb(numa ,numb))
            times = strlen(numa);//比较两个字符串长度,以大的作为循环次数
            else //交换位置以降低难度
            {
            times = strlen(numb);//让数(字符串)长的减去数(字符串)短的
            pna = findend(numb);//交换指针
            pnb = findend(numa);
            along=(int)strlen(numb);//标记数字a的长度;
            blong=(int)strlen(numa);//标记数字b的长度;
            isnegative=1;//标记最后要加上负号
            }
            while ((times-- && (times>=0))|| carry != 0)//carry != 0 说没有借位时
            {
            if(!pstart->next)//如果当前为空结点,则申请新结点
            {
            pnew = new Node;
            pnew -> data = 0;
            pnew -> next = NULL;
            pnew -> ahead = pstart;
            pstart -> next = pnew;
            }
            if(times<0)//如果计算完之后,借位等于1,,说明必然为负值;
            {
            pstart -> data  = -3 ;//让它等于负号 '-'//-3来源于负号与0相差3。。                break;
            }
            else
            {
            if ( *pna == *pnb )//减数等于被减数时。结果等于直截相减的结果;并置借位为0
            {
            if(carry==0)pstart -> data = (*pna-48)-(*pnb-48); //111-11的情况
            else
            {
            pstart->data = (*pna-48)-(*pnb-48)+10 -carry;//1121-1112
            carry=1;
            }
            }
            if( *pna > *pnb )//减数大于被减数时。结果等于直截相减的结果;并置借位为0
            {
            pstart -> data = (*pna-48)-(*pnb-48)-carry;  //存贮个位
            carry=0;
            }
            else if( *pna < *pnb )//说明被减数大于减数,让结果加10,相当于借位 (carry)为1
            {
            if(times>0) pstart->data = (*pna-48)-(*pnb-48)+10 -carry;//13-5的情况作为新值
            else  pstart->data = (*pnb-48)-(*pna-48) -carry; //3-5  作为当前的新值
            carry=1;
            }
            }
            pstart = pstart -> next;          //结点移动
            blong--;
            if(blong>0)pnb--;//指针移向被减数高位
            else *pnb=48;//之后相减就变为了0不作任何运算,其实可以优化的。但代码会长!而且还需要重新开结点。所以放弃;
            pna--;//被数指针移动,
            }
            if(isnegative==1)////加上负号处理。增加一长度并置为负号
            {
            pnew = new Node;
            pnew -> data = 0;
            pnew -> next = NULL;
            pnew -> ahead = pstart;
            pstart -> next = pnew;
            pstart->data=-3;//因为寻找链表的结尾点要统一加48。又因为‘-’是45。所以等于‘-3’
            }
            pstart =head;//寻找链表的结尾点
            while(pstart->next != 0)
            {
            pstart->data += 48;//!!<<<因为我们的输出是字符。所以再此加上48>>>>  逆顺输出
            pstart = pstart->next ;
            }
            int tip = 0;//转为字符串用
            clear0=0;//  消除结果最前面无用的'0'  13-5 = 08 的效果  ..>>修改字符串的首指针
            pstart = pstart->ahead ;//找有效字
            while(pstart != 0)//输出正序的结果;
            {
            if (clear0==0 && ((int)pstart->data)==48&&pstart->ahead!=0)//  消除结果最前面无用的'0'
            ;//不输出任何东西
            else
            result[tip++] = pstart->data;
            if(((int)pstart->data)!=48&&((int)pstart->data)!=45)clear0=1;//'-'号
            pstart = pstart->ahead ;
            }
            result[tip] = '\0';
            pstart =head;  //释放空间
            while(pstart->next != 0)
            {
            pnew = pstart->next ;delete pstart;
            pstart =pnew;
            }
            return ;
            }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -