看网课的时候,跟着学了一下计算器,但是老师只讲了int型的计算,
于是自己研究了一下double型的,结果还真是遇到了不少麻烦;
因为我用的是VS2017 wsprintf 不支持 浮点数 找了好多网上的帖子,但是C语言的没找到合适的
所以自己用整数 小数分开处理的方式解决了一下(如果哪位有更好的办法,请指点)
运行过程中先后发现了一些小bug,已经处理
1、对于分开处理的小数部分,如果是负数,会在小数点后出现“-”号,已经处理
2、当精度选择为“0”时,两数相除,结果为 -1~0 之间会出现“-”号丢失的情况,原因是转 int ,已经处理
3、 当精度选择为“0”时,四舍五入时,整数 ++ 负数 –,已经处理,并且,最后只有整数部分转为TCHAR
4、精度选择非 0,两数相除为负数,且整数部分等于 0 的,会丢失 “-”号,已经处理
5、当两数计算记过整数(小数部分为“0”)时,精度选择除0,1外,其他均不增加尾部的“0”
程序界面的日历 和 时间 菜单 图片 是随便放置的 只是为了记录一下,相关代码及插件的用法,可以忽略
后面还有两种代码,都不是很完善,留作纪念吧,怎么说也记录了我的“折腾”
闲话不多说了
计算器功能:
1、double 型处理 (保证计算结果准确性)
2、精度选择(这里精度设定,恰好与getcursel取值一致,省去了变量)
3、计算结果,四舍五入(正+负-)
4、因为计算精度那里也用的buttion,所以也实现了计算功能
运行截图
乘法
除法
加法
减法
最终代码如下:(后面两种代码,仅为记录,请忽略
/*RM Calculator
Powered By RedMaple
双精度计算,精度0-7可选
四舍五入*/
#include <Windows.h>
#include <Windowsx.h>
#include <Mmsystem.h>
#include "resource.h"
INT_PTR CALLBACK DlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam);
VOID CALLBACK LocalTimerProc(HWND hDlg, UINT message, UINT iTimerID, DWORD dwTime);
INT_PTR CALLBACK _COMMAND(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam);
HINSTANCE hgInst;
int WINAPI WinMain(HINSTANCE hThisApp, HINSTANCE hPrevApp, LPSTR lpCmd, int nShow)
{
hgInst = hThisApp;
HWND hdlg = CreateDialog(hThisApp, MAKEINTRESOURCE(IDD_DIALOGRedMaple), GetDesktopWindow(), (DLGPROC)DlgProc);
if (!hdlg)
{
return 0;
}
ShowWindow(hdlg, SW_SHOW);
UpdateWindow(hdlg);
SetTimer(hdlg, 1, 1000, &LocalTimerProc);//设置定时器
MSG msg;
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return 0;
}
INT_PTR CALLBACK DlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch (msg)
{
case WM_INITDIALOG:
{ // 设置对话框的图标
SendMessage(hDlg, WM_SETICON, IDI_ICONRMC, (LPARAM)LoadIcon(hgInst, MAKEINTRESOURCE(IDI_ICONRMC)));
/*初始化运算符号 “+,-,*,/”*/
HWND COMBOBOXJJCC = GetDlgItem(hDlg, IDC_COMBOjjcc);
ComboBox_InsertString(COMBOBOXJJCC, -1, TEXT("+"));
ComboBox_InsertString(COMBOBOXJJCC, -1, TEXT("-"));
ComboBox_InsertString(COMBOBOXJJCC, -1, TEXT("*"));
ComboBox_InsertString(COMBOBOXJJCC, -1, TEXT("/"));
ComboBox_SetCurSel(COMBOBOXJJCC, 0);//设置默认运算为“+”
/*初始化精度 “0,1,2,3,4,5,6,7”*///恰好和句柄index一致
HWND COMBOBOXJD = GetDlgItem(hDlg, IDC_COMBOJD);
ComboBox_InsertString(COMBOBOXJD, -1, TEXT("0"));
ComboBox_InsertString(COMBOBOXJD, -1, TEXT("1"));
ComboBox_InsertString(COMBOBOXJD, -1, TEXT("2"));
ComboBox_InsertString(COMBOBOXJD, -1, TEXT("3"));
ComboBox_InsertString(COMBOBOXJD, -1, TEXT("4"));
ComboBox_InsertString(COMBOBOXJD, -1, TEXT("5"));
ComboBox_InsertString(COMBOBOXJD, -1, TEXT("6"));
ComboBox_InsertString(COMBOBOXJD, -1, TEXT("7"));
ComboBox_SetCurSel(COMBOBOXJD, 2);//设置默认精度为“2”,小数点后保留2位
}
case WM_COMMAND:
{
_COMMAND(hDlg, msg, wParam,lParam);//函数调用
}
break;
case WM_SYSCOMMAND:
if (wParam == SC_CLOSE)
{
PostQuitMessage(0);//退出
}
return 0;
}
return (INT_PTR)FALSE;
}
INT_PTR CALLBACK _COMMAND(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch (wParam)
{
case IDC_BUTTON2JD://精度按钮,触发计算
case IDC_BUTTON1DH://等于按钮,触发计算
{
//设置缓存
TCHAR strc1[256];
TCHAR strc2[256];
TCHAR strc3[256];
//获取字符串
GetDlgItemText(hDlg, IDC_EDIT1, strc1, sizeof(strc1));
GetDlgItemText(hDlg, IDC_EDIT2, strc2, sizeof(strc2));
//转换字符串 to double
double i1 = _wtof(strc1);
double i2 = _wtof(strc2);
double i3 = 0;//计算结果
//获取运算符选择情况
HWND COMBOBOXJJCC = GetDlgItem(hDlg, IDC_COMBOjjcc);
int count = ComboBox_GetCurSel(COMBOBOXJJCC);
//计算
switch (count)
{
case 0:
{
i3 = i1 + i2;
}
break;
case 1:
{
i3 = i1 - i2;
}
break;
case 2:
{
i3 = i1 * i2;
}
break;
case 3:
{
i3 = i1 / i2;
}
break;
}
//_gcvt_s(strc3,sizeof(strc3),i3, 15 );
//获取精度选择情况
HWND COMBOBOXJD = GetDlgItem(hDlg, IDC_COMBOJD);
int curjd = ComboBox_GetCurSel(COMBOBOXJD);
//double 类型转 TCHAR,没有找到很好的函数,所以自己写了
//方法是将 double分为整数部分和小数部分分别转换为 int
//然后用 wsprintf 转 TCHAR
//实现精度可选,四舍五入,
int j;
int i3integer = (int)i3;//整数部分
int i3decimal;//小数部分
//根据精度计算小数部分,i3tem为临时变量
double i3tem = i3- i3integer;
if (i3tem < 0)//符号转换,避免小数点后出现"-"号
{
i3tem = -1* i3tem ;
}
//小数部分转整数
for (j = 0; j < curjd; j++)
{
i3tem *= 10;
}
//小数部分有效取值(int)
i3decimal = (int)i3tem;
//有效位,下一位四舍五入计算
if (((i3tem - (int)i3tem))*10 > 4)
{
i3decimal++;
}
//精度选择 0 的处理
if (0 == curjd)
{
if (i3 < 0 && (int)i3 == 0)//两数相除为负数,且整数部分等于 0 的处理
{
i3integer = 0;//因为不能显示"-0",所以符号另作处理
}
else
{
if (i3tem * 10 >= 5 && (int)i3 > 0)//正数 5入 整数部分 +1
{
i3integer++;
}
else if (i3tem * 10 >= 5 && (int)i3 < 0)//负数 5入 整数部分 -1
{
i3integer--;
}
}
wsprintf(strc3, L"%d", i3integer);//字符串中只保留整数部分
}
else//精度选择非 0 的处理
{
if (i3 < 0 && (int)i3 == 0)//两数相除为负数,且整数部分等于 0 的处理
{
wsprintf(strc3, L"-0.%d", i3decimal);//手动添加 -0. 只存入小数部分
}
else//正常情况下,将整数部分 "." 小数部分存入字符串
{
wsprintf(strc3, L"%d.%d", i3integer, i3decimal);
}
}
SetDlgItemText(hDlg, IDC_EDIT3, strc3);//显示结果
}
break;
case ID_OK:
{
MessageBox(hDlg, TEXT("确定按键被按下"), TEXT("按键选择"), MB_OK);
}
break;
case ID_CANCEL:
{
MessageBox(hDlg, TEXT("取消按键被按下,即将退出"), TEXT("按键选择"), MB_OK);
PostQuitMessage(0);//退出
}
break;
}
return 0;
}
//定时器,显示时钟
VOID CALLBACK LocalTimerProc(HWND hDlg, UINT message, UINT iTimerID, DWORD dwTime)
{
SYSTEMTIME slt;
GetLocalTime(&slt);
TCHAR ltime[256];
wsprintf(ltime, L"%d年%d月%d日 %d:%d:%d", slt.wYear, slt.wMonth, slt.wDay,
slt.wHour, slt.wMinute, slt.wSecond);
//SetDlgItemText(hDlg, IDC_EDITTIME, ltime);
HWND hwndEdit = GetDlgItem(hDlg, IDC_EDITTIME);
Edit_SetText(hwndEdit, ltime);
}
以下是不完善的代码,仅作为记录:
/*int数据类型计算器*/
#include <Windows.h>
#include <Windowsx.h>
#include <Mmsystem.h>
#include "resource.h"
INT_PTR CALLBACK DlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam);
VOID CALLBACK LocalTimerProc(HWND hDlg, UINT message, UINT iTimerID, DWORD dwTime);
INT_PTR CALLBACK _COMMAND(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam);
HINSTANCE hgInst;
int WINAPI WinMain(HINSTANCE hThisApp, HINSTANCE hPrevApp, LPSTR lpCmd, int nShow)
{
hgInst = hThisApp;
HWND hdlg = CreateDialog(hThisApp, MAKEINTRESOURCE(IDD_DIALOGRedMaple), GetDesktopWindow(), (DLGPROC)DlgProc);
if (!hdlg)
{
return 0;
}
ShowWindow(hdlg, SW_SHOW);
UpdateWindow(hdlg);
SetTimer(hdlg, 1, 1000, &LocalTimerProc);//设置定时器
MSG msg;
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return 0;
}
INT_PTR CALLBACK DlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch (msg)
{
case WM_INITDIALOG:
{ // 设置对话框的图标
//SendMessage(hDlg, WM_SETICON, IDI_ICONRM, (LPARAM)LoadIcon(hgInst, MAKEINTRESOURCE(IDC_EDIT1)));
HWND COMBOBOXJJCC = GetDlgItem(hDlg, IDC_COMBOjjcc);
ComboBox_InsertString(COMBOBOXJJCC, -1, TEXT("+"));
ComboBox_InsertString(COMBOBOXJJCC, -1, TEXT("-"));
ComboBox_InsertString(COMBOBOXJJCC, -1, TEXT("*"));
ComboBox_InsertString(COMBOBOXJJCC, -1, TEXT("/"));
}
case WM_COMMAND:
{
_COMMAND(hDlg, msg, wParam,lParam);
}
break;
case WM_SYSCOMMAND:
if (wParam == SC_CLOSE)
{
PostQuitMessage(0);//退出
}
return 0;
}
return (INT_PTR)FALSE;
}
INT_PTR CALLBACK _COMMAND(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch (wParam)
{
case IDC_BUTTON1:
{
TCHAR strc1[256];
TCHAR strc2[256];
TCHAR strc3[256];
//char strc3[256];
GetDlgItemText(hDlg, IDC_EDIT1, strc1, sizeof(strc1));
GetDlgItemText(hDlg, IDC_EDIT2, strc2, sizeof(strc2));
int i1 = _wtoi(strc1);
int i2 = _wtoi(strc2);
int i3 = 0;
HWND COMBOBOXJJCC = GetDlgItem(hDlg, IDC_COMBOjjcc);
int count = ComboBox_GetCurSel(COMBOBOXJJCC);
switch (count)
{
case 0:
{
i3 = i1 + i2;
}
break;
case 1:
{
i3 = i1 - i2;
}
break;
case 2:
{
i3 = i1 * i2;
}
break;
case 3:
{
i3 = i1 / i2;
}
break;
}
//_gcvt_s(strc3,sizeof(strc3),i3, 15 );
wsprintf(strc3, L"%d", i3);
SetDlgItemText(hDlg, IDC_EDIT3, strc3);
}
break;
case ID_OK:
{
MessageBox(hDlg, TEXT("确定按键被按下"), TEXT("按键选择"), MB_OK);
}
break;
case ID_CANCEL:
{
MessageBox(hDlg, TEXT("取消按键被按下,即将退出"), TEXT("按键选择"), MB_OK);
PostQuitMessage(0);//退出
}
break;
}
return 0;
}
VOID CALLBACK LocalTimerProc(HWND hDlg, UINT message, UINT iTimerID, DWORD dwTime)
{
SYSTEMTIME slt;
GetLocalTime(&slt);
TCHAR ltime[256];
wsprintf(ltime, L"%d年%d月%d日 %d:%d:%d", slt.wYear, slt.wMonth, slt.wDay,
slt.wHour, slt.wMinute, slt.wSecond);
//SetDlgItemText(hDlg, IDC_EDITTIME, ltime);
HWND hwndEdit = GetDlgItem(hDlg, IDC_EDITTIME);
Edit_SetText(hwndEdit, ltime);
}
/*DOUBLE类型数值计算器*/
#include <Windows.h>
#include <Windowsx.h>
#include <Mmsystem.h>
#include "resource.h"
INT_PTR CALLBACK DlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam);
VOID CALLBACK LocalTimerProc(HWND hDlg, UINT message, UINT iTimerID, DWORD dwTime);
INT_PTR CALLBACK _COMMAND(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam);
HINSTANCE hgInst;
int WINAPI WinMain(HINSTANCE hThisApp, HINSTANCE hPrevApp, LPSTR lpCmd, int nShow)
{
hgInst = hThisApp;
HWND hdlg = CreateDialog(hThisApp, MAKEINTRESOURCE(IDD_DIALOGRedMaple), GetDesktopWindow(), (DLGPROC)DlgProc);
if (!hdlg)
{
return 0;
}
ShowWindow(hdlg, SW_SHOW);
UpdateWindow(hdlg);
SetTimer(hdlg, 1, 1000, &LocalTimerProc);//设置定时器
MSG msg;
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return 0;
}
INT_PTR CALLBACK DlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch (msg)
{
case WM_INITDIALOG:
{ // 设置对话框的图标
//SendMessage(hDlg, WM_SETICON, IDI_ICONRM, (LPARAM)LoadIcon(hgInst, MAKEINTRESOURCE(IDC_EDIT1)));
HWND COMBOBOXJJCC = GetDlgItem(hDlg, IDC_COMBOjjcc);
ComboBox_InsertString(COMBOBOXJJCC, -1, TEXT("+"));
ComboBox_InsertString(COMBOBOXJJCC, -1, TEXT("-"));
ComboBox_InsertString(COMBOBOXJJCC, -1, TEXT("*"));
ComboBox_InsertString(COMBOBOXJJCC, -1, TEXT("/"));
}
case WM_COMMAND:
{
_COMMAND(hDlg, msg, wParam,lParam);
}
break;
case WM_SYSCOMMAND:
if (wParam == SC_CLOSE)
{
PostQuitMessage(0);//退出
}
return 0;
}
return (INT_PTR)FALSE;
}
INT_PTR CALLBACK _COMMAND(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch (wParam)
{
case IDC_BUTTON1:
{
TCHAR strc1[256];
TCHAR strc2[256];
TCHAR strc31[256];
char strc3[256];
GetDlgItemText(hDlg, IDC_EDIT1, strc1, sizeof(strc1));
GetDlgItemText(hDlg, IDC_EDIT2, strc2, sizeof(strc2));
double i1 = _wtof(strc1);
double i2 = _wtof(strc2);
double i3 = 0;
HWND COMBOBOXJJCC = GetDlgItem(hDlg, IDC_COMBOjjcc);
int count = ComboBox_GetCurSel(COMBOBOXJJCC);
switch (count)
{
case 0:
{
i3 = i1 + i2;
}
break;
case 1:
{
i3 = i1 - i2;
}
break;
case 2:
{
i3 = i1 * i2;
}
break;
case 3:
{
i3 = i1 / i2;
}
break;
}
_gcvt_s(strc3,sizeof(strc3),i3, 15 );
//wsprintfA(strc3, "%lf", i3);
SetDlgItemTextA(hDlg, IDC_EDIT3, strc3);
}
break;
case ID_OK:
{
MessageBox(hDlg, TEXT("确定按键被按下"), TEXT("按键选择"), MB_OK);
}
break;
case ID_CANCEL:
{
MessageBox(hDlg, TEXT("取消按键被按下,即将退出"), TEXT("按键选择"), MB_OK);
PostQuitMessage(0);//退出
}
break;
}
return 0;
}
VOID CALLBACK LocalTimerProc(HWND hDlg, UINT message, UINT iTimerID, DWORD dwTime)
{
SYSTEMTIME slt;
GetLocalTime(&slt);
TCHAR ltime[256];
wsprintf(ltime, L"%d年%d月%d日 %d:%d:%d", slt.wYear, slt.wMonth, slt.wDay,
slt.wHour, slt.wMinute, slt.wSecond);
//SetDlgItemText(hDlg, IDC_EDITTIME, ltime);
HWND hwndEdit = GetDlgItem(hDlg, IDC_EDITTIME);
Edit_SetText(hwndEdit, ltime);
}
今天的文章简单方便计算器_double类型输出会四舍五入吗[通俗易懂]分享到此就结束了,感谢您的阅读。
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/83730.html