说明
本代码使用easyx绘制计算器界面,同时使用高精度算法实现大整数的连续运算
前提准备
需要安装easyx图形库,具体安装和使用流程请点击链接查看
代码怎么用
需要新建一个工程,向工程中添加头文件和源代码,或者先把所有头文件都提取出来放到一个新的cpp(虽然是c语言,但是easyx底层实现用到了很多c++的东西,所以需要放在cpp文件中,但是语法仍使用c语言)文件中,之后把下面所有块中的函数都提到这一个文件中,因为没有使用全局变量,所以不需要考虑函数接口的问题,直接放在一起就可以使用
头文件1
#ifndef _calculator_h
#define _calculator_h
#include <graphics.h>
#include <windows.h>
#include <conio.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <time.h>
void menu();
void mouse_infor();
void input_num(char *str
, char *str_all
, int &str_len
, int &str_all_len
, char num
);
void calculate(char *ans
, char *str
, int &str_len
, char *str_all
, int &str_all_len
, int &loca
, int step
, char op
);
#endif
头文件2
#ifndef _ALGORITHM_H
#define _ALGORITHM_H
#include<stdio.h>
#include<string.h>
#include<math.h>
#include<time.h>
#include<stdlib.h>
#include<conio.h>
#define _FOR(i, begin, end) for(i=begin; i<=end; ++i)
#define _for(i, begin, end) for(i=begin; i>=end; --i)
void add(char *ans
, char *num
);
int compare(char *num_b
, char *num_c
);
void subtract(char *ans
, char *num
);
void multiply(char *ans
, char *num
);
void division(char *ans
, char *num
);
void mod(char *ans
, char *num
);
int SubStract(int *numb
, int *numc
);
void str_to_num(char *str
, int *num
);
#endif
主函数
#include"calculator.h"
#include"high_precision_algorithm.h"
int main()
{
initgraph(600, 500);
cleardevice();
setbkcolor(BLACK
);
menu();
mouse_infor();
closegraph();
return 0;
}
计算器界面绘制
#include"calculator.h"
#include"high_precision_algorithm.h"
void menu()
{
loadimage(NULL, _T("space.jpg"));
setcolor(DARKGRAY
);
line(0, 45, 600, 45);
line(280, 158, 520, 158);
line(280, 271, 520, 271);
line(280, 384, 520, 384);
line(520, 110, 600, 110);
line(520, 175, 600, 175);
line(520, 240, 600, 240);
line(520, 305, 600, 305);
line(520, 370, 600, 370);
line(520, 435, 600, 435);
line(280, 45, 280, 500);
line(360, 45, 360, 500);
line(440, 45, 440, 500);
line(520, 45, 520, 500);
settextstyle(30, 0, _T("幼圆"));
settextcolor(RGB(153,100,254));
outtextxy(180, 0, _T("大整数的四则运算"));
settextcolor(RGB(153,100,254));
settextstyle(60, 40, _T("幼圆"));
outtextxy(305, 75, _T("7"));
outtextxy(385, 75, _T("8"));
outtextxy(465, 75, _T("9"));
outtextxy(300, 188, _T("4"));
outtextxy(380, 188, _T("5"));
outtextxy(460, 188, _T("6"));
outtextxy(300, 301, _T("1"));
outtextxy(380, 301, _T("2"));
outtextxy(460, 301, _T("3"));
outtextxy(380, 414, _T("0"));
settextstyle(30, 0, _T("幼圆"));
outtextxy(303, 414, _T("历"));
outtextxy(303, 460, _T("史"));
outtextxy(463, 414, _T("清"));
outtextxy(463, 460, _T("零"));
settextcolor(RGB(153,100,254));
settextstyle(60, 0, _T("幼圆"));
outtextxy(545, 46, _T("<"));
outtextxy(545, 111, _T("+"));
outtextxy(545, 176, _T("-"));
outtextxy(545, 241, _T("*"));
outtextxy(545, 306, _T("/"));
outtextxy(545, 371, _T("%"));
outtextxy(545, 436, _T("="));
}
鼠标信息捕获及对应处理
#include"calculator.h"
#include"high_precision_algorithm.h"
void mouse_infor()
{
char ans
[100], str
[100], str_all
[100];
int str_len
= 0, str_all_len
= 0;
int loca
= 50, step
= 40;
MOUSEMSG m
;
memset(ans
, 0, sizeof(ans
));
memset(str
, 0, sizeof(str
));
memset(str_all
, 0, sizeof(str_all
));
while(1)
{
if(loca
> 500)
{
loca
= 50;
cleardevice();
setbkcolor(BLACK
);
menu();
}
m
= GetMouseMsg();
if(m
.uMsg
== WM_LBUTTONDOWN
)
{
if(m
.x
>280 && m
.x
<360 && m
.y
>45 && m
.y
<158)
input_num(str
, str_all
, str_len
, str_all_len
, '7');
if(m
.x
>360 && m
.x
<440 && m
.y
>45 && m
.y
<158)
input_num(str
, str_all
, str_len
, str_all_len
, '8');
if(m
.x
>440 && m
.x
<520 && m
.y
>45 && m
.y
<158)
input_num(str
, str_all
, str_len
, str_all_len
, '9');
if(m
.x
>280 && m
.x
<360 && m
.y
>158 && m
.y
<271)
input_num(str
, str_all
, str_len
, str_all_len
, '4');
if(m
.x
>360 && m
.x
<440 && m
.y
>158 && m
.y
<271)
input_num(str
, str_all
, str_len
, str_all_len
, '5');
if(m
.x
>440 && m
.x
<520 && m
.y
>158 && m
.y
<271)
input_num(str
, str_all
, str_len
, str_all_len
, '6');
if(m
.x
>280 && m
.x
<360 && m
.y
>271 && m
.y
<384)
input_num(str
, str_all
, str_len
, str_all_len
, '1');
if(m
.x
>360 && m
.x
<440 && m
.y
>271 && m
.y
<384)
input_num(str
, str_all
, str_len
, str_all_len
, '2');
if(m
.x
>440 && m
.x
<520 && m
.y
>271 && m
.y
<384)
input_num(str
, str_all
, str_len
, str_all_len
, '3');
if(m
.x
>360 && m
.x
<440 && m
.y
>384 && m
.y
<500)
input_num(str
, str_all
, str_len
, str_all_len
, '0');
if(m
.x
>520 && m
.x
<600 && m
.y
>45 && m
.y
<110)
{
if(strlen(str
) != 0)
{
str
[--str_len
] = '\0';
str_all
[--str_all_len
] = '\0';
}
}
if(m
.x
>520 && m
.x
<600 && m
.y
>175 && m
.y
<240)
{
if(strlen(ans
)==0 && strlen(str
)==0)
{
str
[str_len
++] = '-';
str_all
[str_all_len
++] = '-';
}
else
{
calculate(ans
, str
, str_len
, str_all
, str_all_len
, loca
, step
, '-');
}
}
if(strlen(ans
) == 0)
{
cleardevice();
setbkcolor(BLACK
);
menu();
setcolor(GREEN
);
settextstyle(40, 0, _T("幼圆"));
loca
= 50;
outtextxy(0, loca
, _T(str
));
}
if(m
.x
>280 && m
.x
<360 && m
.y
>384 && m
.y
<500)
{
loca
+= step
;
setcolor(GREEN
);
settextstyle(30, 0, _T("幼圆"));
outtextxy(0, loca
, _T("历史记录查看:"));
loca
+= step
;
if(strlen(str_all
) != 0)
outtextxy(0, loca
, _T(str_all
));
else
outtextxy(0, loca
, _T("历史记录为空"));
}
if(m
.x
>440 && m
.x
<520 && m
.y
>384 && m
.y
<500)
{
memset(ans
, 0, sizeof(ans
));
memset(str
, 0, sizeof(str
));
memset(str_all
, 0, sizeof(str_all
));
str_len
= str_all_len
= 0;
loca
= 50;
cleardevice();
setbkcolor(BLACK
);
menu();
setcolor(GREEN
);
settextstyle(40, 0, _T("幼圆"));
outtextxy(0, loca
, _T("历史记录已删除"));
}
if(m
.x
>520 && m
.x
<600 && m
.y
>110 && m
.y
<175)
{
calculate(ans
, str
, str_len
, str_all
, str_all_len
, loca
, step
, '+');
}
if(m
.x
>520 && m
.x
<600 && m
.y
>240 && m
.y
<305)
{
calculate(ans
, str
, str_len
, str_all
, str_all_len
, loca
, step
, '*');
}
if(m
.x
>520 && m
.x
<600 && m
.y
>305 && m
.y
<370)
{
calculate(ans
, str
, str_len
, str_all
, str_all_len
, loca
, step
, '/');
}
if(m
.x
>520 && m
.x
<600 && m
.y
>370 && m
.y
<435)
{
calculate(ans
, str
, str_len
, str_all
, str_all_len
, loca
, step
, '%');
}
}
}
}
计算
#include"calculator.h"
#include"high_precision_algorithm.h"
void calculate(char *ans
, char str
[], int &str_len
, char *str_all
, int &str_all_len
, int &loca
, int step
, char op
)
{
int i
;
MOUSEMSG m
;
if(loca
!=50 || strlen(ans
)==0)
loca
+= step
;
setcolor(GREEN
);
settextstyle(40, 0, _T("幼圆"));
outtextxy(0, loca
, _T(op
));
str_all
[str_all_len
++] = op
;
if(strlen(str
)!=0 && str
[0]!='+' && str
[0]!='-')
{
for(i
=strlen(str
); i
>=1; i
--)
{
str
[i
] = str
[i
-1];
}
str
[0] = '+';
}
if(strlen(ans
) == 0)
{
strcpy(ans
, str
);
str_len
= 0;
memset(str
, 0, strlen(str
));
}
loca
+= step
;
while(1)
{
m
= GetMouseMsg();
if(m
.uMsg
== WM_LBUTTONDOWN
)
{
if(m
.x
>280 && m
.x
<360 && m
.y
>45 && m
.y
<158)
input_num(str
, str_all
, str_len
, str_all_len
, '7');
if(m
.x
>360 && m
.x
<440 && m
.y
>45 && m
.y
<158)
input_num(str
, str_all
, str_len
, str_all_len
, '8');
if(m
.x
>440 && m
.x
<520 && m
.y
>45 && m
.y
<158)
input_num(str
, str_all
, str_len
, str_all_len
, '9');
if(m
.x
>280 && m
.x
<360 && m
.y
>158 && m
.y
<271)
input_num(str
, str_all
, str_len
, str_all_len
, '4');
if(m
.x
>360 && m
.x
<440 && m
.y
>158 && m
.y
<271)
input_num(str
, str_all
, str_len
, str_all_len
, '5');
if(m
.x
>440 && m
.x
<520 && m
.y
>158 && m
.y
<271)
input_num(str
, str_all
, str_len
, str_all_len
, '6');
if(m
.x
>280 && m
.x
<360 && m
.y
>271 && m
.y
<384)
input_num(str
, str_all
, str_len
, str_all_len
, '1');
if(m
.x
>360 && m
.x
<440 && m
.y
>271 && m
.y
<384)
input_num(str
, str_all
, str_len
, str_all_len
, '2');
if(m
.x
>440 && m
.x
<520 && m
.y
>271 && m
.y
<384)
input_num(str
, str_all
, str_len
, str_all_len
, '3');
if(m
.x
>360 && m
.x
<440 && m
.y
>384 && m
.y
<500)
input_num(str
, str_all
, str_len
, str_all_len
, '0');
if(m
.x
>520 && m
.x
<600 && m
.y
>45 && m
.y
<110)
{
if(strlen(str
) != 0)
{
str
[--str_len
] = '\0';
str_all
[--str_all_len
] = '\0';
}
}
if(m
.x
>520 && m
.x
<600 && m
.y
>175 && m
.y
<240)
{
if(strlen(str
) == 0)
{
str
[str_len
++] = '-';
str_all
[str_all_len
++] = '-';
}
}
HRGN rgn
= CreateRectRgn(0, loca
, 280, loca
+step
);
setcliprgn(rgn
);
clearcliprgn();
DeleteObject(rgn
);
setcliprgn(NULL);
outtextxy(0, loca
, _T(str
));
if(m
.x
>520 && m
.x
<600 && m
.y
>435 && m
.y
<500)
{
break;
}
}
}
if(strlen(str
)!=0 && str
[0]!='+' && str
[0]!='-')
{
for(i
=strlen(str
); i
>=1; i
--)
{
str
[i
] = str
[i
-1];
}
str
[0] = '+';
}
switch(op
)
{
case '+': add(ans
, str
); break;
case '-': subtract(ans
, str
); break;
case '*': multiply(ans
, str
); break;
case '/': division(ans
, str
); break;
case '%': mod(ans
, str
); break;
}
str_len
= 0;
memset(str
, 0, strlen(str
));
loca
+= step
;
outtextxy(0, loca
, _T("="));
if(ans
[0]=='+' || ans
[1]=='0')
outtextxy(10, loca
, _T(ans
+1));
else
outtextxy(10, loca
, _T(ans
));
}
高精度加法
#include"calculator.h"
#include"high_precision_algorithm.h"
void add(char *ans
, char *num
)
{
int len_max
;
int cnt
, begin
;
int sum
, carry
;
int i
, flag_b
, flag_c
;
int num_b
[100], num_c
[100], num_tmp
[100];
cnt
= 1;
sum
= carry
= 0;
flag_b
= ans
[0]=='-'?1:0;
flag_c
= num
[0]=='-'?1:0;
memset(num_b
, 0, sizeof(num_b
));
memset(num_c
, 0, sizeof(num_c
));
memset(num_tmp
, 0, sizeof(num_tmp
));
if(flag_b
==0 && flag_c
==1)
{
num
[0] = '+';
subtract(ans
, num
);
}
else if(flag_b
==1 && flag_c
==0)
{
ans
[0] = '+';
subtract(ans
, num
);
if(ans
[0] == '+') ans
[0] = '-';
else if(ans
[0] = '-') ans
[0] = '+';
}
else if(flag_b
==1 && flag_c
==1)
{
ans
[0] = '+';
num
[0] = '+';
add(ans
, num
);
ans
[0] = '-';
}
else if(flag_b
==0 && flag_c
==0)
{
memset(num_b
, 0, sizeof(num_b
));
memset(num_c
, 0, sizeof(num_c
));
memset(num_tmp
, 0, sizeof(num_tmp
));
str_to_num(ans
, num_b
), memset(ans
, 0, strlen(ans
));
str_to_num(num
, num_c
);
len_max
= max(num_b
[0], num_c
[0]);
_FOR(i
, 1, len_max
)
{
sum
= num_b
[i
] + num_c
[i
] + carry
;
num_tmp
[i
] = sum
%10;
carry
= sum
/10;
}
if(carry
!= 0)
{
num_tmp
[len_max
+1] = carry
;
num_tmp
[0] = len_max
+1;
}
else num_tmp
[0] = len_max
;
begin
= num_tmp
[0];
_for(i
, begin
, 1)
{
ans
[cnt
++] = num_tmp
[i
] + '0';
}
ans
[0] = '+';
}
}
高精度减法
#include"calculator.h"
#include"high_precision_algorithm.h"
void subtract(char *ans
, char *num
)
{
int cnt
, begin
, tag
;
int i
, flag_b
, flag_c
;
int num_b
[100], num_c
[100], num_tmp
[100];
cnt
= 1;
flag_b
= ans
[0]=='-'?1:0;
flag_c
= num
[0]=='-'?1:0;
if(flag_b
==0 && flag_c
==1)
{
num
[0] = '+';
add(ans
, num
);
}
else if(flag_b
==1 && flag_c
==0)
{
ans
[0] = '+';
add(ans
, num
);
ans
[0] = '-';
}
else if(flag_b
==1 && flag_c
==1)
{
ans
[0] = '+';
num
[0] = '+';
subtract(ans
, num
);
if(ans
[0] == '+') ans
[0] = '-';
else if(ans
[0] == '-') ans
[0] = '+';
}
else if(flag_b
==0 && flag_c
==0)
{
memset(num_b
, 0, sizeof(num_b
));
memset(num_c
, 0, sizeof(num_c
));
memset(num_tmp
, 0, sizeof(num_tmp
));
tag
= compare(ans
, num
);
str_to_num(ans
, num_b
), memset(ans
, 0, strlen(ans
));
str_to_num(num
, num_c
);
if(tag
== 0) ans
[0] = '+', ans
[1]='0';
else if(tag
== 1)
{
_FOR(i
, 1, num_b
[0])
{
if(num_b
[i
] < num_c
[i
])
{
num_b
[i
+1]--;
num_b
[i
] += 10;
}
num_tmp
[i
] = num_b
[i
] - num_c
[i
];
}
begin
= num_b
[0];
while(num_tmp
[begin
] == 0) begin
--;
_for(i
, begin
, 1)
{
ans
[cnt
++] = num_tmp
[i
] +'0';
}
ans
[0] = '+';
}
else
{
_FOR(i
, 0, num_c
[0])
{
if(num_c
[i
] < num_b
[i
])
{
num_c
[i
+1]--;
num_c
[i
] += 10;
}
num_tmp
[i
] = num_c
[i
] - num_b
[i
];
}
begin
= num_c
[0];
while(num_tmp
[begin
] == 0) begin
--;
_for(i
, begin
, 1)
{
ans
[cnt
++] = num_tmp
[i
] +'0';
}
ans
[0] = '-';
}
}
}
高精度乘法
#include"calculator.h"
#include"high_precision_algorithm.h"
void multiply(char *ans
, char *num
)
{
int cnt
, begin
;
int i
, j
, flag_b
, flag_c
;
int str_len
= 0, str_all_len
= 0;
int num_b
[100], num_c
[100], num_tmp
[100];
char str_all
[200], str
[200];
cnt
= 1;
flag_b
= ans
[0]=='-'?1:0;
flag_c
= num
[0]=='-'?1:0;
if(flag_b
==0 && flag_c
==1)
{
num
[0] = '+';
multiply(ans
, num
);
ans
[0] = '-';
}
else if(flag_b
==1 && flag_c
==0)
{
ans
[0] = '+';
multiply(ans
, num
);
ans
[0] = '-';
}
else if(flag_b
==1 && flag_c
==1)
{
ans
[0] = '+';
num
[0] = '+';
multiply(ans
, num
);
ans
[0] = '+';
}
else if(flag_b
==0 && flag_c
==0)
{
memset(num_b
, 0, sizeof(num_b
));
memset(num_c
, 0, sizeof(num_c
));
memset(num_tmp
, 0, sizeof(num_tmp
));
str_to_num(ans
, num_b
), memset(ans
, 0, strlen(ans
));
str_to_num(num
, num_c
);
_FOR(i
, 1, num_b
[0])
{
_FOR(j
, 1, num_c
[0])
{
num_tmp
[i
+j
] += num_b
[i
]*num_c
[j
]%10;
num_tmp
[i
+j
+1] += num_b
[i
]*num_c
[j
]/10;
}
}
begin
= num_b
[0] + num_c
[0] + 1;
while(num_tmp
[begin
]==0 && begin
>2) begin
--;
_FOR(i
, 2, begin
)
{
if(num_tmp
[i
] >= 10)
{
num_tmp
[i
+1] += num_tmp
[i
] / 10;
num_tmp
[i
] %=10;
if(i
== begin
)
{
begin
++;
}
}
}
_for(i
, begin
, 2) ans
[cnt
++] = num_tmp
[i
] + '0';
ans
[0] = '+';
}
}
高精度除法
#include"calculator.h"
#include"high_precision_algorithm.h"
void division(char *ans
, char *num
)
{
int cnt
, begin
;
int i
, j
, flag_b
, flag_c
;
int len_tmp
, digits
;
int str_len
= 0, str_all_len
= 0;
int num_b
[100], num_c
[100], num_tmp
[100];
cnt
= 1;
flag_b
= ans
[0]=='-'?1:0;
flag_c
= num
[0]=='-'?1:0;
memset(num_b
, 0, sizeof(num_b
));
memset(num_c
, 0, sizeof(num_c
));
memset(num_tmp
, 0, sizeof(num_tmp
));
if(flag_b
==0 && flag_c
==1)
{
num
[0] = '+';
division(ans
, num
);
ans
[0] = '-';
}
else if(flag_b
==1 && flag_c
==0)
{
ans
[0] = '+';
division(ans
, num
);
ans
[0] = '-';
}
else if(flag_b
==1 && flag_c
==1)
{
ans
[0] = '+';
num
[0] = '+';
division(ans
, num
);
ans
[0] = '+';
}
else if(flag_b
==0 && flag_c
==0)
{
memset(num_b
, 0, sizeof(num_b
));
memset(num_c
, 0, sizeof(num_c
));
memset(num_tmp
, 0, sizeof(num_tmp
));
str_to_num(ans
, num_b
);
str_to_num(num
, num_c
);
digits
= num_b
[0] - num_c
[0];
if(compare(ans
, num
) == 0) memset(ans
, 0, strlen(ans
)), ans
[0] = '+', ans
[1] = '1';
else if(compare(ans
, num
) == -1) memset(ans
, 0, strlen(ans
)), ans
[0] = '+', ans
[1] = '0';
else
{
_for(i
, num_b
[0], 1)
{
if(i
> digits
)
num_c
[i
] = num_c
[i
- digits
];
else
num_c
[i
] = 0;
}
num_c
[0] = num_b
[0];
_FOR(i
, 1, digits
+1)
{
while((len_tmp
= SubStract(num_b
, num_c
)) >= 0)
{
num_tmp
[digits
+ 2 - i
]++;
}
num_c
[0]--;
_FOR(j
, 1, num_c
[0]) num_c
[j
] = num_c
[j
+1]; num_c
[num_c
[0]+1] = 0;
}
begin
= digits
+ 1;
while(num_tmp
[begin
] == 0 && begin
> 1) begin
--;
num_tmp
[0] = begin
;
memset(ans
, 0, strlen(ans
));
_for(i
, num_tmp
[0], 1)
{
ans
[cnt
++] = num_tmp
[i
] + '0';
}
ans
[0] = '+';
}
}
}
高精度取余
#include"calculator.h"
#include"high_precision_algorithm.h"
void mod(char *ans
, char *num
)
{
char ans_tmp
[100];
memset(ans_tmp
, 0, sizeof(ans_tmp
));
strcpy(ans_tmp
, ans
);
division(ans_tmp
, num
);
multiply(ans_tmp
, num
);
subtract(ans
, ans_tmp
);
}
里面自定义的一些函数
比较两数大小
#include"calculator.h"
#include"high_precision_algorithm.h"
int compare(char *num_b
, char *num_c
)
{
if(strlen(num_b
) == strlen(num_c
))
{
if(strcmp(num_b
, num_c
) == 0) return 0;
else if(strcmp(num_b
, num_c
) > 0) return 1;
else return -1;
}
else if(strlen(num_b
) > strlen(num_c
)) return 1;
else return -1;
}
将数据写入数组
#include"calculator.h"
#include"high_precision_algorithm.h"
void input_num(char *str
, char *str_all
, int &str_len
, int &str_all_len
, char num
)
{
str
[str_len
++] = num
;
str_all
[str_all_len
++] = num
;
}
字符串转变为数字
#include"calculator.h"
#include"high_precision_algorithm.h"
void str_to_num(char *str
, int *num
)
{
int i
, cnt
, len
;
int end
, size
;
size
= 0;
cnt
= 1;
len
= strlen(str
);
if(str
[0]=='+' || str
[0]=='-') end
= 1;
else end
= 0;
_for(i
, len
-1, end
)
{
num
[cnt
++] = str
[i
]-'0';
size
++;
}
num
[0] = size
;
}
除法中用到的减法(如果不明白这个“减法”,再理解下高精度除法的思想)
#include"calculator.h"
#include"high_precision_algorithm.h"
int SubStract(int *num_b
, int *num_c
)
{
int i
;
int len_b
= num_b
[0];
int len_c
= num_c
[0];
if(len_b
< len_c
) return -1;
else if(len_b
== len_c
)
{
_for(i
, len_b
, 1)
{
if(num_b
[i
] > num_c
[i
]) break;
else if(num_b
[i
] < num_c
[i
]) return -1;
}
}
_FOR(i
, 1, len_b
)
{
if(num_b
[i
] < num_c
[i
])
{
num_b
[i
+1]--;
num_b
[i
] += 10;
}
num_b
[i
] -= num_c
[i
];
}
_for(i
, len_b
, 1)
{
if(num_b
[i
] != 0)
{
num_b
[0] = i
;
return i
;
}
}
num_b
[0] = 0;
return 0;
}