好資料,51黑有你更精彩!!!樓主的主程序:
- #include "yunsuan.h"
- u8 jshcq[16]={0}; //計算結(jié)果緩存區(qū)
- _SU shushu1={0,0,{0,0,0,0,0,0,0,0,0,0,0,0,0,0}}; //前數(shù)
- _SU shushu2={0,0,{0,0,0,0,0,0,0,0,0,0,0,0,0,0}}; //后數(shù)
- extern u8 da; //定義靜態(tài)變量da,對應(yīng)LCD顯示字符位置
- /**********************************************
- *功能:LCD顯示數(shù)組清零
- **********************************************/
- void Lcd_qinpin(void)
- {
- u8 i; //定義變量i
- for(i=0;i<16;i++){ //循環(huán)16次
- lcdxs[i]=' '; //LCD顯示字符數(shù)組清空
- }
- }
- /**********************************************************************************************************************************
- *功能:LCD輸入顯示算式限制函數(shù)
- 目的:限制字符的輸入顯示。
- 情況分析:1、兩個數(shù)首位都不能是無意義的0。 例如,00.12。
- 2、兩個數(shù)的小數(shù)點最多都只能有1個。例如,12.3.4。
- 3、兩個數(shù)首位只能是數(shù)字。 例如,.5898。
- 4、兩個數(shù)尾位都不能是無效的0。 例如,65.30。
- 5、算式中運算符必須有1個。 例如,567。
- (情況分析后補,具體看程序)
- zhuangtai對應(yīng)位說明:
- bit[2-0] : 前個顯示字符對應(yīng)的標號(fenzu)。
- bit[3] : 0)當前輸入數(shù)首位數(shù)字不是0, 1)當前輸入數(shù)首位數(shù)字是0。
- bit[4] : 0)字符不顯示, 1)顯示字符。
- bit[5] : 0)算式后數(shù)沒小數(shù)點, 1)算式后數(shù)有小數(shù)點。
- bit[6] : 0)算式前數(shù)沒小數(shù)點, 1)算式前數(shù)有小數(shù)點。
- bit[7] : 0)當前算式?jīng)]有輸入過運算符, 1)當前算式有輸入過運算符。
- 輸入算式滿了的情況下,只能按等號鍵有效,通過da判斷實現(xiàn)。
- **********************************************************************************************************************************/
- u8 Shizhe_Xianzhi(u8 x)
- {
- static u8 zhuangtai=0x04; //給定zhuangtai的初值0x04,為什么是0x04?分析知道首位的限制情況和前一個字符是運算符類似
- u8 fenzu=0; //定義變量fenzu,作用如下
- //-------------給輸入按鍵情況分類-------------
- if(x=='0'){ //輸入'0'
- if(da<16){
- fenzu=1; //fenzu=1
- }
- }else{
- if(x>'0'){
- if(x=='='){ //輸入'='
- fenzu=5; //fenzu=5
- }else{ //輸入'123456789'
- if(da<16){
- fenzu=2; //fenzu=2
- }
- }
- }else{
- if(x=='.'){ //輸入'.'
- if(da<16){
- fenzu=3; //fenzu=3
- }
- }else{ //輸入'+-*/'
- if(da<16){
- fenzu=4; //fenzu=4
- }
- }
- }
- }
- zhuangtai&=0xef; //zhuangtai字符顯示標志位置0
- //---------------------按等號鍵的后續(xù)處理-----------------------------------------
- if((zhuangtai&0x07)==0x06){ //上一個狀態(tài)是清除'='按下
- zhuangtai=0x04; //zhuangtai恢復(fù)初始值
- }
- if((zhuangtai&0x07)==0x05){ //上一個狀態(tài)是計算'='按下
- if(fenzu==5){ //計算完算式,需再次按'='清屏處理,不然不執(zhí)行任何操作
- zhuangtai=0x06; //zhuangtai恢復(fù)初始值
- zhuangtai|=0x10; //zhuangtai字符顯示標志位置1
- return zhuangtai; //跳出準備執(zhí)行清屏與相關(guān)數(shù)據(jù)初始化工作
- }else{
- return zhuangtai; //跳出,無操作
- }
- }
- //-------------------------------------按fenzu分類處理--------------------------------------------------------------------------
- switch(fenzu)
- {
- case 1:
- if((zhuangtai&0x0f)!=0x09){ //排除一種情況:當前輸入數(shù)首位數(shù)字是0,并且前一個字符是'0'
- if((zhuangtai&0x07)==0x04){ //兩種情況:剛開始輸入、前一個字符是運算符
- zhuangtai|=0x08; //zhuangtai第3位置位
- }
- zhuangtai&=0xf8; //zhuangtai清零后3位
- zhuangtai|=0x11; //zhuangtai字符顯示標志位置1、zhuangtai添加后3位狀態(tài)值(1)
- }
- break;
- case 2:
- if((zhuangtai&0x0f)!=0x09){ //排除一種情況:當前輸入數(shù)首位數(shù)字是0,并且前一個字符是'0'
- zhuangtai&=0xf8; //zhuangtai清零后3位
- zhuangtai|=0x12; //zhuangtai字符顯示標志位置1、zhuangtai添加后3位狀態(tài)值(2)
- }
- break;
- case 3:
- //排除情況:前一個字符是小數(shù)點、前一個字符是運算符、當前算式有小數(shù)點沒有運算符、當前算式有運算符有小數(shù)點
- if(((zhuangtai&0x07)!=0x03)&&((zhuangtai&0x07)!=0x04)&&((zhuangtai&0xc0)!=0x40)&&((zhuangtai&0xa0)!=0xa0)){
- zhuangtai&=0xf8; //zhuangtai清零后3位
- if(zhuangtai&0x80){ //當前算式有運算符
- zhuangtai|=0x20; //zhuangtai第5位置位
- }else{ //當前算式?jīng)]有運算符
- zhuangtai|=0x40; //zhuangtai第6位置位
- }
- zhuangtai&=0xf7; //zhuangtai第3位(首位數(shù)字0標志位)清零(有小數(shù)點后,首位是不是0,對輸入數(shù)字字符沒影響)
- zhuangtai|=0x13; //zhuangtai字符顯示標志位置1、zhuangtai添加后3位狀態(tài)值(3)
- }
- break;
- case 4:
- //排除情況:前一個字符是小數(shù)點、前一個字符是運算符、前數(shù)有小數(shù)點前一個字符是0、算式輸入過一次運算符
- if(((zhuangtai&0x07)!=0x03)&&((zhuangtai&0x07)!=0x04)&&((zhuangtai&0xc7)!=0x41)&&((zhuangtai&0x80)!=0x80)){
- zhuangtai&=0xf8; //zhuangtai清零后3位
- zhuangtai&=0xf7; //zhuangtai第3位(首位數(shù)字0標志位)清零
- zhuangtai|=0x94; //zhuangtai字符顯示標志位置1、zhuangtai第7位置位、zhuangtai添加后3位狀態(tài)值(4)
- }
- break;
- case 5:
- //排除情況:前一個字符是小數(shù)點、前一個字符是運算符、后數(shù)有小數(shù)點前一個字符是0、算式?jīng)]輸入過運算符
- if(((zhuangtai&0x07)!=0x03)&&((zhuangtai&0x07)!=0x04)&&((zhuangtai&0xa7)!=0xa1)&&(zhuangtai&0x80)){
- zhuangtai&=0xf8; //zhuangtai清零后3位
- zhuangtai|=0x15; //zhuangtai字符顯示標志位置1、zhuangtai添加后3位狀態(tài)值(5)
- }else{
- //輸入算式不合理的情況下
- zhuangtai=0x16; //zhuangtai字符顯示標志位置1、zhuangtai添加后3位狀態(tài)值(6)
- }
- break;
- default:
- break;
- }
- //--------------------------------------------------------------------------------------------------------------------------------
- return zhuangtai; //返回按鍵狀態(tài)值
- }
- /**********************************************************************************************************
- *功能:結(jié)構(gòu)體數(shù)據(jù)隨輸入字符改變
- 目的:隨著輸入字符,改變相應(yīng)的結(jié)構(gòu)體數(shù)據(jù)(用于四則運算)。
- 具體情況:記錄,shushu1.zscd //前數(shù)整數(shù)個數(shù)
- shushu1.sscd //前數(shù)小數(shù)個數(shù)
- shushu1.shujuabc[] //去除小數(shù)點后的前數(shù)數(shù)據(jù)
- shushu2.zscd //后數(shù)整數(shù)個數(shù)
- shushu2.sscd //后數(shù)小數(shù)個數(shù)
- shushu2.shujuabc[] //去除小數(shù)點后的后數(shù)數(shù)據(jù)
- **********************************************************************************************************/
- void Jiegou_Chuli(u8 xcu)
- {
- static u8 i=0,xs=0,ys=0; //定義變量i對應(yīng)shujuabc[]標號,變量xs對應(yīng)小數(shù)點,變量ys對應(yīng)運算符
- if(xcu!='='){ //按下的不是等號鍵
- if(xcu>='0'){ //輸入數(shù)字
- if(xs==0){
- if(ys==0){ //(輸入算式?jīng)]小數(shù)點、沒運算符)前數(shù)整數(shù)部分
- shushu1.zscd++; //前數(shù)整數(shù)對應(yīng)個數(shù)加一
- shushu1.shujuabc[i]=xcu-0x30; //輸入字符數(shù)字存入shushu1.shujuabc[]
- }else{ //(輸入算式?jīng)]小數(shù)點、有運算符)后數(shù)整數(shù)部分
- shushu2.zscd++; //后數(shù)整數(shù)對應(yīng)個數(shù)加一
- shushu2.shujuabc[i]=xcu-0x30; //輸入字符數(shù)字存入shushu2.shujuabc[]
- }
- }else{
- if(xs==1){
- if(ys==0){ //(輸入算式有一個小數(shù)點、沒運算符)前數(shù)小數(shù)部分
- shushu1.sscd++; //前數(shù)小數(shù)對應(yīng)個數(shù)加一
- shushu1.shujuabc[i]=xcu-0x30; //輸入字符數(shù)字存入shushu1.shujuabc[]
- }else{ //(輸入算式前數(shù)有小數(shù)點、有運算符)后數(shù)整數(shù)部分
- shushu2.zscd++; //后數(shù)整數(shù)對應(yīng)個數(shù)加一
- shushu2.shujuabc[i]=xcu-0x30; //輸入字符數(shù)字存入shushu2.shujuabc[]
- }
- }else{ //(輸入算式后數(shù)有小數(shù)點、有運算符)后數(shù)小數(shù)部分
- shushu2.sscd++; //后數(shù)小數(shù)對應(yīng)個數(shù)加一
- shushu2.shujuabc[i]=xcu-0x30; //輸入字符數(shù)字存入shushu2.shujuabc[]
- }
- }
- i++; //變量i加一
- }else{
- if(xcu=='.'){ //是小數(shù)點
- if(ys==0){ //當前沒有運算符
- xs=1; //xs=1,表示前數(shù)有小數(shù)點了
- }else{ //當前有運算符
- xs=2; //xs=2,表示后數(shù)有小數(shù)點了
- }
- }else{ //是運算符
- i=0; //變量i置零,開始對應(yīng)后數(shù)存儲數(shù)組shujuabc[]
- ys=1; //ys=1,表示運算符有了
- }
- }
- }else{ //按下的是等號鍵
- i=0; //變量初始化,準備下次運算
- xs=0;
- ys=0;
- }
- }
- /*********************************************************************************************
- *功能:結(jié)構(gòu)體數(shù)據(jù)初始化
- 目的:結(jié)構(gòu)體數(shù)據(jù)和計算結(jié)果存儲數(shù)組初始化,為下次運算準備。
- *********************************************************************************************/
- void Jiegou_Csh(void)
- {
- //---------初始化結(jié)構(gòu)體數(shù)據(jù)和計算結(jié)果存儲數(shù)組---------
- u8 i; //定義變量i
- shushu1.zscd=0; //前數(shù)整數(shù)個數(shù)置零
- shushu1.sscd=0; //前數(shù)小數(shù)個數(shù)置零
- shushu2.zscd=0; //后數(shù)整數(shù)個數(shù)置零
- shushu2.sscd=0; //后數(shù)小數(shù)個數(shù)置零
- for(i=0;i<14;i++){ //循環(huán)14次
- shushu1.shujuabc[i]=0; //前數(shù)數(shù)據(jù)清零
- shushu2.shujuabc[i]=0; //后數(shù)數(shù)據(jù)清零
- jshcq[i]=0; //計算結(jié)果存儲數(shù)組前14位清零
- }
- jshcq[14]=0; //計算結(jié)果存儲數(shù)組15位清零
- jshcq[15]=0; //計算結(jié)果存儲數(shù)組16位清零
- }
- /********************************************************************************************************************
- *功能:運算符判斷
- 目的:以運算符分類處理四則運算。
- ********************************************************************************************************************/
- u8 Yunsf_Jl(void)
- {
- u8 ysf; //ysf用作運算符記錄
- if(shushu1.sscd==0){ //沒有小數(shù)部分
- ysf=lcdxs[shushu1.zscd]; //前數(shù)的整數(shù)部分長度就是運算符在lcdxs[]中的位置
- }else{ //有小數(shù)部分
- ysf=lcdxs[shushu1.zscd+shushu1.sscd+1]; //前數(shù)的整數(shù)部分加前數(shù)的小數(shù)部分長度再加小數(shù)位就是運算符在lcdxs[]中的位置
- }
- return ysf; //返回ysf
- }
- /**********************************************************************************************************************************************************
- *功能:乘法函數(shù)
- **********************************************************************************************************************************************************/
- u8 Chengfa(void)
- {
- u8 ic=0,jc=0,nc=0,mc=0; //前數(shù)開始運算位,后數(shù)開始運算位,計算結(jié)果存儲位置變量,計算結(jié)果存儲起始位
- ic=shushu1.zscd+shushu1.sscd-1; //賦值“前數(shù)的的尾位在shushu1.shujuabc[]中的位置”給ic
- jc=shushu2.zscd+shushu2.sscd-1; //賦值“后數(shù)的的尾位在shushu2.shujuabc[]中的位置”給jc
- if(((ic==0)&&(shushu1.shujuabc[ic]==0))||((jc==0)&&(shushu2.shujuabc[jc]==0))){ //前數(shù)和后數(shù)中至少一個是0
- jshcq[0]=0; //顯示計算結(jié)果'0'
- return 0xf0; //跳出
- }
- //----------------------------循環(huán)0---------------------------------------------------------
- do
- {
- jshcq[nc]+=shushu2.shujuabc[jc]*shushu1.shujuabc[ic]; //存儲兩數(shù)運算結(jié)果
- if(jshcq[nc]>9){ //兩數(shù)運算結(jié)果是2位數(shù)
- jshcq[nc+1]+=jshcq[nc]/10; //高位累加進位
- jshcq[nc]%=10; //低位取個位
- }
- if(ic!=0){ //前數(shù)數(shù)據(jù)沒取完
- ic--; //前數(shù)運算位左移
- nc++; //運算結(jié)果存儲位右移
- }else{ //前數(shù)數(shù)據(jù)取完了
- if(jc!=0){ //后數(shù)數(shù)據(jù)沒取完
- ic=shushu1.zscd+shushu1.sscd-1; //前數(shù)起始位初始值
- jc--; //后數(shù)運算位左移
- mc++; //存儲結(jié)果起始位右移
- nc=mc; //賦值給nc
- }else{ //后數(shù)數(shù)據(jù)取完了
- if(jshcq[nc+1]!=0){ //如果計算完有進位
- nc++; //相應(yīng)的nc加一
- }
- break; //跳出循環(huán) <<<====(循環(huán)0,出口)
- }
- }
- }while(1);
- //--------------------------------------------------------------------------------------------
- jc=15; //jc賦值15,作用不同上面
- if((shushu1.sscd!=0)||(shushu2.sscd!=0)){ //前數(shù)和后數(shù)中至少有一個有小數(shù)點
- jc=nc-(shushu1.sscd+shushu2.sscd); //計算結(jié)果總長度(不算小數(shù)點)-兩個數(shù)小數(shù)部分長度和。jc是小數(shù)點在lcdxs[]中的位置
- }
- mc=(jc<<4)+nc; //高四位存小數(shù)點位,低四位存計算結(jié)果長度
- return mc; //帶出mc
- }
- /***************************************************************************************************************************************
- *功能:加法函數(shù)
- ***************************************************************************************************************************************/
- u8 Jiafa(void)
- {
- u8 ic=0,jc=0,nc=0,mc=0; //前數(shù)開始運算位,后數(shù)開始運算位,計算結(jié)果存儲位置變量,計算結(jié)果存儲起始位
- ic=shushu1.zscd+shushu1.sscd-1; //賦值“前數(shù)的的尾位在shushu1.shujuabc[]中的位置”給ic
- jc=shushu2.zscd+shushu2.sscd-1; //賦值“后數(shù)的的尾位在shushu2.shujuabc[]中的位置”給jc
- //-------------------處理前數(shù)和后數(shù)小數(shù)位較長的部分--------------------------
- if(shushu1.sscd>shushu2.sscd){ //前數(shù)的小數(shù)部分比后數(shù)的小數(shù)部分長
- do
- {
- if(ic-shushu1.zscd==jc-shushu2.zscd){ //直到取到小數(shù)位一樣長后
- break; //跳出 <<<====(出口)
- }else{
- jshcq[nc]+=shushu1.shujuabc[ic]; //小數(shù)位長的直接賦值給jshcq[]
- nc++; //存儲位遞加
- ic--; //移位取下一位小數(shù)位
- }
- }while(1);
- mc=shushu1.sscd; //小數(shù)點位置計算用到
- }else{
- if(shushu1.sscd!=shushu2.sscd){ //小數(shù)位等長不用處理
- do
- {
- if(ic-shushu1.zscd==jc-shushu2.zscd){ //直到取到小數(shù)位一樣長后
- break; //跳出 <<<====(出口)
- }else{
- jshcq[nc]+=shushu2.shujuabc[jc]; //小數(shù)位長的直接賦值給jshcq[]
- nc++; //存儲位遞加
- jc--; //移位取下一位小數(shù)位
- }
- }while(1);
- }
- mc=shushu2.sscd; //小數(shù)點位置計算用到
- }
- //-------------------處理另一部分--------------------------------------------------
- do
- {
- jshcq[nc]+=shushu1.shujuabc[ic]+shushu2.shujuabc[jc]; //兩數(shù)中間部分相加
- if(jshcq[nc]>9){ //兩數(shù)運算結(jié)果是2位數(shù)
- jshcq[nc+1]+=jshcq[nc]/10; //高位累加進位
- jshcq[nc]%=10; //低位取個位
- }
- if((ic!=0)&&(jc!=0)){ //兩個數(shù)數(shù)據(jù)都沒取完
- nc++;
- ic--;
- jc--;
- }else{
- if((ic==0)&&(jc==0)){ //兩個數(shù)數(shù)據(jù)都取完
- break; //跳出 <<<====(出口)
- }else{
- if(ic==0){ //前數(shù)數(shù)據(jù)取完
- //-------------------后數(shù)整數(shù)部分長出的部分處理---------------------------
- do{
- if(jc==0){
- break; //跳出 <<<====(出口)
- }else{
- nc++;
- jc--;
- }
- jshcq[nc]+=shushu2.shujuabc[jc]; //后數(shù)整數(shù)長的部分再取
- if(jshcq[nc]>9){ //兩數(shù)運算結(jié)果是2位數(shù)
- jshcq[nc+1]+=jshcq[nc]/10; //高位累加進位
- jshcq[nc]%=10; //低位取個位
- }
- }while(1);
- //------------------------------------------------------------------------
- }else{ //后數(shù)數(shù)據(jù)取完
- //-------------------前數(shù)整數(shù)部分長出的部分處理---------------------------
- do{
- if(ic==0){
- break; //跳出 <<<====(出口)
- }else{
- nc++;
- ic--;
- }
- jshcq[nc]+=shushu1.shujuabc[ic]; //前數(shù)整數(shù)長的部分再取
- if(jshcq[nc]>9){ //兩數(shù)運算結(jié)果是2位數(shù)
- jshcq[nc+1]+=jshcq[nc]/10; //高位累加進位
- jshcq[nc]%=10; //低位取個位
- }
- }while(1);
- //------------------------------------------------------------------------
- }
- break; //跳出
- }
- }
- }while(1);
- if(jshcq[nc+1]>0){ //高位有進位的情況
- nc++;
- }
- //------------------------------------------------------------------------------------
- jc=15;
- if((shushu1.sscd!=0)||(shushu2.sscd!=0)){
- jc=nc-mc; //計算結(jié)果總長度(不算小數(shù)點)-小數(shù)部分長度。小數(shù)點在lcdxs[]中的位置
- }
- mc=(jc<<4)+nc; //高四位存小數(shù)點位,低四位存計算結(jié)果長度
- return mc;
- }
- /******************************************************************************************************************************************
- *功能:減法函數(shù)
- ******************************************************************************************************************************************/
- u8 Jianfa(void)
- {
- u8 ic=0,jc=0,nc=0,mc=0;
- //-----------------------------比較前數(shù)和后數(shù)的大小---------------------------------------------------------------------
- if(shushu1.zscd>shushu2.zscd){ //前數(shù)整數(shù)部分比后數(shù)整數(shù)部分長
- mc=1; //前數(shù)比后數(shù)大
- }else{
- if(shushu1.zscd!=shushu2.zscd){ //前數(shù)整數(shù)部分比后數(shù)整數(shù)部分短
- mc=2; //后數(shù)比前數(shù)大
- }else{ //前數(shù)整數(shù)部分和后數(shù)整數(shù)部分一樣長
- do
- {
- if(shushu1.shujuabc[ic]>shushu2.shujuabc[jc]){ //前數(shù)高位比后數(shù)高位大
- mc=1;
- break; //跳出
- }else{
- if(shushu1.shujuabc[ic]!=shushu2.shujuabc[jc]){ //前數(shù)高位比后數(shù)高位小
- mc=2;
- break; //跳出
- }else{ //前數(shù)高位和后數(shù)高位一樣大
- if((ic!=shushu1.zscd+shushu1.sscd-1)&&(jc!=shushu2.zscd+shushu2.sscd-1)){ //前數(shù)和后數(shù)數(shù)據(jù)都沒有取完
- ic++;
- jc++;
- }else{
- if((ic==shushu1.zscd+shushu1.sscd-1)&&(jc==shushu2.zscd+shushu2.sscd-1)){ //前數(shù)和后數(shù)數(shù)據(jù)都取完
- mc=0; //前數(shù)和后數(shù)一樣大
- break; //跳出
- }else{
- if(ic==shushu1.zscd+shushu1.sscd-1){ //前數(shù)數(shù)據(jù)取完,后數(shù)沒取完
- mc=2;
- break; //跳出
- }else{ //后數(shù)數(shù)據(jù)取完,前數(shù)沒取完
- mc=1;
- break; //跳出
- }
- }
- }
- }
- }
- }while(1);
- }
- }
- //-----------------------------------------------------------------------------------------------------------------------
- ic=shushu1.zscd+shushu1.sscd-1;
- jc=shushu2.zscd+shushu2.sscd-1;
- switch(mc)
- {
- case 0:
- jshcq[0]=0; //顯示計算結(jié)果'0'
- break;
- case 1: //與下面mc=2是一樣的,下面?zhèn)渥⒃敿汓c
- if(shushu1.sscd>=shushu2.sscd){ //前數(shù)不比后數(shù)小數(shù)部分短
- do
- {
- if(ic-shushu1.zscd==jc-shushu2.zscd){ //直到取到小數(shù)位一樣長后
- break; //跳出
- }else{
- jshcq[nc]=shushu1.shujuabc[ic]; //小數(shù)位長的直接賦值給jshcq[]
- nc++; //存儲位遞加
- ic--; //移位取下一位小數(shù)位
- }
- }while(1);
- }else{ //前數(shù)比后數(shù)小數(shù)部分短
- shushu1.shujuabc[ic]--; //減一
- jshcq[nc]=10-shushu2.shujuabc[jc];
- nc++;
- jc--;
- do
- {
- if(ic-shushu1.zscd==jc-shushu2.zscd){ //直到取到小數(shù)位一樣長后
- break; //跳出
- }else{
- jshcq[nc]=9-shushu2.shujuabc[jc];
- nc++; //存儲位遞加
- jc--; //移位取下一位小數(shù)位
- }
- }while(1);
- }
- do
- {
- if(shushu1.shujuabc[ic]>=shushu2.shujuabc[jc]){ //前數(shù)不比后數(shù)小
- jshcq[nc]+=shushu1.shujuabc[ic]-shushu2.shujuabc[jc]; //前數(shù)-后數(shù)
- if(jc==0){ //后數(shù)取完了
- do
- {
- if(ic!=0){ //前數(shù)沒取完
- nc++;
- ic--;
- }else{
- break;
- }
- jshcq[nc]+=shushu1.shujuabc[ic];
- }while(1);
- break; //前數(shù)取完跳出循環(huán)
- }else{
- ic--;
- jc--;
- nc++;
- }
- }else{ //前數(shù)比后數(shù)小
- shushu1.shujuabc[ic]+=10; //加10
- if(shushu1.shujuabc[ic-1]!=0){ //當前運算前數(shù)的前一位不等于0
- shushu1.shujuabc[ic-1]--; //減一位
-
- }else{ //當前運算前數(shù)的前一位等于0
- mc=ic; //mc的作用變了
- ic--;
- do
- {
- shushu1.shujuabc[ic]=9; //0位置9
- if(shushu1.shujuabc[ic-1]!=0){ //找可以減的位
- shushu1.shujuabc[ic-1]--; //減一
- break; //跳出
- }else{ //再找
- ic--;
- }
- }while(1);
- ic=mc;
- }
- }
- }while(1);
- break;
- case 2:
- if(shushu2.sscd>=shushu1.sscd){ //后數(shù)不比前數(shù)小數(shù)部分短 <<<=====(分情況實現(xiàn))
- //---------------------------------------------------------------------------------------------------
- do
- {
- if(ic-shushu1.zscd==jc-shushu2.zscd){ //直到取到小數(shù)位一樣長后 <<<=====(目的)
- break; //跳出
- }else{
- jshcq[nc]=shushu2.shujuabc[jc]; //小數(shù)位長的直接賦值給jshcq[]
- nc++; //存儲位遞加
- jc--; //移位取下一位小數(shù)位
- }
- }while(1);
- //---------------------------------------------------------------------------------------------------
- }else{ //后數(shù)比前數(shù)小數(shù)部分短
- //--------------------------------------------------------------------------------------------------
- shushu2.shujuabc[jc]--; //減一
- jshcq[nc]=10-shushu1.shujuabc[ic];
- nc++;
- ic--;
- do
- {
- if(ic-shushu1.zscd==jc-shushu2.zscd){ //直到取到小數(shù)位一樣長后 <<<=====(目的)
- break; //跳出
- }else{
- jshcq[nc]=9-shushu1.shujuabc[ic];
- nc++; //存儲位遞加
- ic--; //移位取下一位小數(shù)位
- }
- }while(1);
- //--------------------------------------------------------------------------------------------------
- }
- //-----------------------------循環(huán)0-------------------------------------------------------------------
- do
- {
- if(shushu2.shujuabc[jc]>=shushu1.shujuabc[ic]){ //后數(shù)不比前數(shù)小
- jshcq[nc]+=shushu2.shujuabc[jc]-shushu1.shujuabc[ic]; //后數(shù)-前數(shù)
- if(ic==0){ //前數(shù)取完了
- //------------------------循環(huán)2-----------------------------------------------------
- do
- {
- if(jc!=0){ //后數(shù)沒取完
- nc++;
- jc--;
- }else{ //后數(shù)取完了
- break; //跳出 <<<====(循環(huán)2,出口)
- }
- jshcq[nc]+=shushu2.shujuabc[jc];
- }while(1);
- //----------------------------------------------------------------------------------
- nc++;
- jshcq[nc]='-'-0x30; //負號先記上
- break; //后數(shù)取完跳出循環(huán) <<<=====(循環(huán)0,出口)
- }else{
- ic--;
- jc--;
- nc++;
- }
- }else{ //后數(shù)比前數(shù)小
- shushu2.shujuabc[jc]+=10; //加10
- if(shushu2.shujuabc[jc-1]!=0){ //當前運算后數(shù)的前一位不等于0
- shushu2.shujuabc[jc-1]--; //減一位
-
- }else{ //當前運算后數(shù)的前一位等于0
- //-------------------------------循環(huán)1---------------------------------------------------------
- mc=jc; //mc的作用變了
- jc--;
- do
- {
- shushu2.shujuabc[jc]=9; //0位置9
- if(shushu2.shujuabc[jc-1]!=0){ //找可以減的位
- shushu2.shujuabc[jc-1]--; //不夠減,高位要 <<<=====(循環(huán)1,目的)
- break; //跳出
- }else{ //再找
- ic--;
- }
- }while(1);
- jc=mc;
- //---------------------------------------------------------------------------------------------
- }
- }
- }while(1);
- //-----------------------------------------------------------------------------------------------------
- break;
- default:
- break;
- }
- jc=15;
- if(shushu1.sscd>=shushu2.sscd){ //沒有多余變量可以利用,只能再判斷一次小數(shù)部分長短
- mc=shushu1.sscd;
- }else{
- mc=shushu2.sscd;
- }
- if((shushu1.sscd!=0)||(shushu2.sscd!=0)){
- jc=nc-mc; //計算結(jié)果總長度(不算小數(shù)點)-小數(shù)部分長度。小數(shù)點在lcdxs[]中的位置
- }
- mc=(jc<<4)+nc; //高四位存小數(shù)點位,低四位存計算結(jié)果長度
- return mc;
- }
- /*********************************************************************************************************
- *功能:除法函數(shù)
- *********************************************************************************************************/
- u8 Chufa(void)
- {
- u8 ic=0,jc=0,nc=0,mc=0,gc=0,xc=0;
- //--------------------------------特殊情況處理-----------------------------------------------------------
- if((shushu2.shujuabc[0]==0)&&(shushu2.zscd==1)&&(shushu2.sscd==0)){ //后數(shù)是0的情況,不進行運算
- Lcd_qinpin(); //LCD顯示數(shù)組清零
- lcdxs[0]='x'; //無法計算結(jié)果
- return 0xff;
- }
- if((shushu1.shujuabc[0]==0)&&(shushu1.zscd==1)&&(shushu1.sscd==0)){ //前數(shù)是0的情況
- Lcd_qinpin(); //LCD顯示數(shù)組清零,準備存儲計算結(jié)果
- lcdxs[0]='0'; //計算結(jié)果是0
- return 0xff;
- }
- //--------------------------------------------------------------------------------------------------------
- while(shushu1.shujuabc[ic]==0){ //前數(shù)是0的位不用運算
- ic++;
- }
- while(shushu2.shujuabc[jc]==0){ //后數(shù)是0的位不用運算
- jc++;
- }
- xc=shushu2.zscd-shushu1.zscd+ic-jc+15; //小數(shù)點位置
- mc=jc<<4; //當前jc值存入mc高四位,jc最大13,4位足以存儲
- //---------------------------------大循環(huán)0號,直到計算出16位計算結(jié)果才跳出------------------------------------------------
- do
- {
- mc&=0xf0; //清除低四位
- mc|=ic; //記錄ic的值,存入mc低四位 (關(guān)鍵點:mc之前的數(shù)據(jù)一定是0)
- if(nc!=16){ //計算結(jié)果沒滿16位
- if((mc&0x0f)>=14-shushu2.zscd-shushu2.sscd){ //“前數(shù)截取部分的長度首位置之后的剩余的長度”不會比“后數(shù)的長度”長
- //----------------------------------循環(huán)1號,為了能計算出足有16位的結(jié)果----------------------------------------------
- jc=0; //這里jc的作用是一個起始值為0的變量
- do
- {
- shushu1.shujuabc[jc]=shushu1.shujuabc[ic]; //將剩余的有效數(shù)字重新以shushu1.shujuabc[0]為起始順序存儲
- shushu1.shujuabc[ic]=0; //清除
- if(ic==13){ //數(shù)據(jù)重存完
- break; //跳出
- }else{ //繼續(xù)轉(zhuǎn)存有效數(shù)據(jù)
- jc++;
- ic++;
- }
- }while(1);
- ic=0; //相應(yīng)的變量值也將改變,實現(xiàn)一個14位數(shù)據(jù)的數(shù)組當一個28位數(shù)據(jù)的數(shù)組使用 <<<====(循環(huán)1號,目的)
- mc&=0xf0; //清除低四位,mc低四位清零,同步ic值
- jc=mc>>4; //jc恢復(fù)初始值
- //-----------------------------------------------------------------------------------------------------------------
- }
- }else{ //得到16位計算結(jié)果 <<<====(大循環(huán)0號,目的)
- break; //跳出
- }
- //-----------------------循環(huán)2號,截取前數(shù)(可減后數(shù),即必須比后數(shù)大)部分-------------------------------------------------------------------------------
- do
- {
- if(shushu1.shujuabc[ic]>shushu2.shujuabc[jc]){ //從高位開始比較
- ic=(mc&0x0f)+shushu2.zscd+shushu2.sscd-1; //前數(shù)截取長度和后數(shù)等長
- break; //跳出(大的時候會跳出) <<<====(出口1)
- }else{
- if(shushu1.shujuabc[ic]!=shushu2.shujuabc[jc]){ //前數(shù)比后數(shù)小
- if(shushu1.shujuabc[ic]!=0){ //該位不是0,前數(shù)截取長度比后數(shù)多1位肯定比后數(shù)大
- ic=(mc&0x0f)+shushu2.zscd+shushu2.sscd; //前數(shù)截取比后數(shù)多1位數(shù)
- if(!(gc&0x80)){ //gc最高位是0,在gc最高位是1的情況下nc不能加加
- nc++; //計算結(jié)果位置移位
- gc|=0x80; //最高位置1,表示前數(shù)截取部分比后數(shù)長1位數(shù)
- }
- }else{ //該位是0
- if(ic==mc){ //0是前數(shù)截取部分第一位
- ic++; //判斷位移位
- mc++; //mc低四位加一同步ic
- jc=mc>>4; //后數(shù)回到起始位置
- gc&=0x7f; //高位置0,表示
- gc|=0x01; //gc最低位作為這一情況的標志,表示不用運算
- nc++;
- }else{ //0是前數(shù)截取部分非首位,首位肯定不是0,這種情況是前數(shù)截取部分減了后數(shù)若干次后的結(jié)果小于后數(shù)了
- ic=(mc&0x0f)+shushu2.zscd+shushu2.sscd; //前數(shù)截取比后數(shù)多1位數(shù)
- if(!(gc&0x80)){ //gc最高位是0,在gc最高位是1的情況下nc不能加加,比如,4480-452=4028,4028-452這種情況nc不能加
- nc++; //計算結(jié)果位置移位
- gc|=0x80; //最高位置1,表示前數(shù)截取部分比后數(shù)長1位數(shù)
- }
- }
- }
- break; //跳出(小的時候跳出) <<<====(出口2)
- }else{ //前數(shù)和后數(shù)高位一樣大
- if(jc!=shushu2.zscd+shushu2.sscd-1){ //后數(shù)數(shù)據(jù)沒有取完,繼續(xù)下位比較
- ic++;
- jc++;
- }else{ //前數(shù)和后數(shù)一樣大
- ic=(mc&0x0f)+shushu2.zscd+shushu2.sscd-1; //前數(shù)截取長度和后數(shù)等長
- break; //跳出(相等的時候跳出) <<<====(出口3)
- }
- }
- }
- }while(1);
- //----------------------------------------------------------------------------------------------------------------------------------------------------
- if(!(gc&0x01)){ //gc最低位是1的時候,不進行運算
- jc=shushu2.zscd+shushu2.sscd-1; //后數(shù)尾數(shù)開始運算
- //------------------------------------循環(huán)3號,前數(shù)截取部分-后數(shù),求得可減次數(shù),化除法為減法----------------------------------------------
- do
- {
- if(shushu1.shujuabc[ic]>=shushu2.shujuabc[jc]){ //前數(shù)不比后數(shù)小
- shushu1.shujuabc[ic]-=shushu2.shujuabc[jc]; //前數(shù)-后數(shù)
- if(jc==mc>>4){ //后數(shù)取完了
- if(ic!=(mc&0x0f)){ //前數(shù)截取部分沒取完
- if(shushu1.shujuabc[ic-1]==0){ //前數(shù)多的一位是0
- gc&=0x7f; //最高位置0,表示如果減后的前數(shù)截取部分長度比后數(shù)小的話,存儲位置nc需要加加
- }else{ //這里說明肯定比后數(shù)還大,存儲位置nc不能移位
- ic--;
- }
- }
- break; //跳出循環(huán) <<<====(循環(huán)3號,出口)
- }else{
- ic--;
- jc--;
- }
- }else{ //前數(shù)比后數(shù)小
- //----------------------------------只進行數(shù)據(jù)改變,不運算-----------------------------------------------------------
- shushu1.shujuabc[ic]+=10; //加10
- if(shushu1.shujuabc[ic-1]!=0){ //當前運算前數(shù)的前一位不等于0
- shushu1.shujuabc[ic-1]--; //減一位
- }else{ //當前運算前數(shù)的前一位等于0
- //-----------------------------循環(huán)4號,尋找可借位高位-----------------------------------------------------------
- gc|=ic; //gc這里的作用是保存當前ic的值,ic最大值13,用gc的低四位足夠
- ic--;
- do
- {
- shushu1.shujuabc[ic]=9; //0位置9
- if(shushu1.shujuabc[ic-1]!=0){ //找可以減的位 <<<====(循環(huán)4號,目的)
- shushu1.shujuabc[ic-1]--; //減一
- break; //跳出
- }else{ //再找
- ic--;
- }
- }while(1);
- ic=gc&0x7f; //ic恢復(fù)原保存值
- gc&=0x80; //保留最高位,清除其他位
- //--------------------------------------------------------------------------------------------------------------
- }
- //-----------------------------------------------------------------------------------------------------------------
- }
- }while(1);
- //------------------------------------------------------------------------------------------------------------------------------------
- jshcq[nc]++; //前數(shù)截取部分和后數(shù)減一次,計算結(jié)果累加一次
- }
- gc&=0x80; //最高位不變,其他位清零
- }while(1);
- //-------------------------------------------------------------------------------------------------------------------------
- Lcd_qinpin(); //LCD顯示數(shù)組清零,準備存儲計算結(jié)果
- jc=0;
- gc=0;
- //-------------------計算結(jié)果和顯示轉(zhuǎn)換--------------------------
- if(xc<16){
- //-----計算結(jié)果大于等于1(還有0.幾的情況在內(nèi))-----------------
- nc=16-xc;
- //-------------------計算結(jié)果數(shù)據(jù)處理--------------------------
- if(jshcq[0]==0&&nc!=1){ //計算結(jié)果首位數(shù)字是0,并且不是0.
- jc++; //起始數(shù)據(jù)位置加一
- nc--; //小數(shù)點位置同步
- }
- //-------------------存入顯示數(shù)組------------------------------
- for(ic=0;ic<16;ic++){ //計算結(jié)果轉(zhuǎn)換為顯示數(shù)據(jù)
- if(ic==nc){ //小數(shù)點位置
- lcdxs[ic]='.';
- }else{ //數(shù)字位置
- lcdxs[ic]=jshcq[jc]+0x30;
- jc++;
- }
- }
- //---------刪除計算結(jié)果后面無效的0----------------------------
- ic=15;
- do
- {
- if(lcdxs[ic]=='0'||lcdxs[ic]=='.'){ //這里存在一種情況,如果一個計算結(jié)果是無理數(shù)并且顯示尾部是0,那么0也會被不顯示,這雖然不是想要的結(jié)果,但還可以接受
- lcdxs[ic]=' ';
- ic--;
- }else{
- break;
- }
- }while(1);
- //---------------------------------------------------------------
- }else{
- //-------------------計算結(jié)果小于1-------------------------------------------
- nc=xc-14;
- //------------計算結(jié)果小于等于0.001采用科學計數(shù)法----------------------------
- if((nc==4&&jshcq[0]==0)||nc>4){
- if(jshcq[0]!=0){ //沒算小數(shù)點的計算結(jié)果首位不是0,nc要減一
- nc--;
- }else{ //首位0不用顯示
- jc++;
- }
- //-------------------固定顯示部分------------------------------------------
- lcdxs[1]='.';
- if(nc<10){
- lcdxs[13]='e';
- lcdxs[14]='-';
- lcdxs[15]=nc+0x30;
- mc=12; //下面刪除無效0不顯示有用
- }else{
- lcdxs[12]='e';
- lcdxs[13]='-';
- lcdxs[14]=nc/10+0x30;
- lcdxs[15]=nc%10+0x30;
- mc=11; //下面刪除無效0不顯示有用
- }
- //-------------------存入顯示數(shù)組------------------------------------------
- for(ic=0;ic<14;ic++){ //計算結(jié)果轉(zhuǎn)換為顯示數(shù)據(jù)
- if(lcdxs[ic]==' '){ //lcdxs[]沒有賦值
- lcdxs[ic]=jshcq[jc]+0x30;
- jc++;
- if(lcdxs[ic]!='0'){ //lcdxs[]只要有一位數(shù)不是0,gc就賦值1
- gc=1;
- }
- }
- }
- //-----------------------特殊情況------------------------------------------
- if(gc==0){ //全是0,表示計算結(jié)果無效
- Lcd_qinpin();
- lcdxs[0]='x'; //顯示x,表示計算不出來,當計算結(jié)果小于1/9999999999999時
- }else{
- do
- {
- if(lcdxs[mc]=='0'||lcdxs[mc]=='.'){ //這里存在一種情況,如果一個計算結(jié)果是無理數(shù)并且顯示尾部是0,那么0也會被不顯示,這雖然不是想要的結(jié)果,但還可以接受,比如,計算結(jié)果9.99000999000e-4會顯示9.99000999e-4
- lcdxs[mc]=' ';
- mc--;
- }else{
- break;
- }
- }while(1);
- }
- //----------------------------------------------------------------------------
- }else{
- //------------計算結(jié)果大于0.001-----------------------------------------
- for(ic=0;ic<16;ic++){ //0和小數(shù)點部分
- if(ic<nc){
- if(ic==1){
- lcdxs[ic]='.';
- }else{
- lcdxs[ic]='0';
- }
- }else{ //其余部分
- lcdxs[ic]=jshcq[jc]+0x30;
- jc++;
- }
- }
- ic=15;
- do
- {
- if(lcdxs[ic]=='0'||lcdxs[ic]=='.'){ //這里存在一種情況,如果一個計算結(jié)果是無理數(shù)并且顯示尾部是0,那么0也會被不顯示,這雖然不是想要的結(jié)果,但還可以接受
- lcdxs[ic]=' ';
- ic--;
- }else{
- break;
- }
- }while(1);
- }
- //-------------------------------------------------------------------------
- }
- //----------------------------------------------------------------------------
- return 0xff;
- }
- /*************************************************************************************************
- *功能:四則運算
- *************************************************************************************************/
- void Jisuan(void)
- {
- u8 yun,u=0;
- yun=Yunsf_Jl();
- switch(yun)
- {
- case '+':
- yun=Jiafa(); //yun的作用變了
- break;
- case '-':
- yun=Jianfa();
- break;
- case '*':
- yun=Chengfa();
- break;
- case '/':
- yun=Chufa();
- break;
- default:
- break;
- }
- if(yun!=0xff){ //排除除法,其他3種算法需執(zhí)行的程序
- Lcd_qinpin(); //LCD顯示數(shù)組清零,準備存儲計算結(jié)果
- do
- {
- lcdxs[u]=jshcq[yun%16]+0x30; //計算結(jié)果存儲數(shù)組中的數(shù)據(jù)以字符形式放入LCD顯示數(shù)組
- if(yun%16!=0){
- if(u==yun/16){ //小數(shù)位處理
- u++;
- lcdxs[u]='.';
- }
- yun--; //jshcq[]存放形式低位到高位
- u++; //lcdxs[]存放形式高位到低位
- }else{ //跳出循壞條件:數(shù)據(jù)取完
- break;
- }
- }while(1);
- //--------------去掉計算結(jié)果后面沒用的0---------------------------比如,34.00
- if(yun/16!=15){ //有小數(shù)點時
- do
- {
- if(lcdxs[u]=='0'){ //碰到'0'
- lcdxs[u]=' '; //空格符代替
- }else{
- if(lcdxs[u]=='.'){ //碰到'.'
- lcdxs[u]=' '; //空格符代替
- }
- break; //碰到非'0'數(shù)字字符跳出
- }
- u--; //移位,判斷下一位
- }while(1);
- }
- //-----------去掉計算結(jié)果前面沒用的0------------------------------比如,00.34
- u=0;
- do
- {
- if(lcdxs[u]=='0'){
- if(lcdxs[u+1]=='.'){
- break; //當計算結(jié)果是'0''.'的時候,跳出循環(huán)
- }else{
- if(lcdxs[u+1]==' '){ //計算結(jié)果是'0'的時候
- break;
- }
- lcdxs[u]=' '; //如果'0'后面沒跟'.'
- u++; //移位,準備下一位判斷
- }
- }else{
- if(lcdxs[u]!='-'){
- break; //碰到不是'-',跳出循環(huán)
- }else{
- u++;
- }
- }
- }while(1);
- }
- }
復(fù)制代碼 |