📄 caledlg.cpp
字号:
// 程序名称:caleDlg.cpp ,计算常数PI到小数点后任意位
// 版 本: 1.0
// 完成时间: 2008年3月
// 作 者: 窦军
// 联系方式: doudoujun@tom.com QQ:78377748
#include "stdafx.h"
#include "cale.h"
#include "caleDlg.h"
#include <math.h>
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
FILE *fp;
int tail, p10tail;
int *arctg5, *arctg239, *tmp;
int DecLen, BinLen;
int x, n, sign, NonZeroPtr;
int Step;
char fn_status[] = "pi_sts.___";
char fn_arctg5[] = "atg5.___";
char fn_arctg239[] = "atg239.___";
char fn_tmp[] = "tmp.___";
void __cdecl FirstDiv(int *arctg_array)
{
__asm {
mov esi, arctg_array
mov dword ptr [esi], 1
xor edx, edx
mov ebx, x
mov ecx, BinLen
fd1: mov eax, [esi]
div ebx
mov [esi], eax
add esi, 4
loop fd1
mov esi, arctg_array
mov edi, tmp
mov ecx, BinLen
pushf
cld
rep movsd
popf
}
}
void __cdecl arctgx(int *arctg_array)
{
int NonZeroBytePtr;
for (;NonZeroPtr<BinLen;) {
NonZeroBytePtr = NonZeroPtr * 4;
__asm {
mov esi, tmp
add esi, NonZeroBytePtr
xor edx, edx
mov ebx, x
mov ecx, BinLen
sub ecx, NonZeroPtr
arctg1: mov eax, [esi]
div ebx
mov [esi], eax
add esi, 4
loop arctg1
cmp sign, 1
jne sub_
mov esi, tmp
add esi, NonZeroBytePtr
mov edi, arctg_array
add edi, NonZeroBytePtr
xor edx, edx
mov ebx, n
mov ecx, BinLen
sub ecx, NonZeroPtr
add_1: mov eax, [esi]
div ebx
add [edi], eax
adc dword ptr [edi-4], 0
jnc add_3
push edi
sub edi, 4
add_2: sub edi, 4
add dword ptr [edi], 1
jc add_2
pop edi
add_3: add esi, 4
add edi, 4
loop add_1
jmp adj_var
sub_: mov esi, tmp
add esi, NonZeroBytePtr
mov edi, arctg_array
add edi, NonZeroBytePtr
xor edx, edx
mov ebx, n
mov ecx, BinLen
sub ecx, NonZeroPtr
sub_1: mov eax, [esi]
div ebx
sub [edi], eax
sbb dword ptr [edi-4], 0
jnc sub_3
push edi
sub edi, 4
sub_2: sub edi, 4
sub dword ptr [edi], 1
jc sub_2
pop edi
sub_3: add esi, 4
add edi, 4
loop sub_1
adj_var: add n, 2
neg sign
mov esi, tmp
add esi, NonZeroBytePtr
cmp dword ptr [esi], 0
jne adj_var_ok
inc NonZeroPtr
adj_var_ok:
}
}
}
void __cdecl mul_array(int *array, int multiplicator)
{
__asm {
mov esi, BinLen
dec esi
shl esi, 2
add esi, array
mov ecx, BinLen
mov ebx, multiplicator
xor edi, edi
mul1: mov eax, [esi]
mul ebx
add eax, edi
adc edx, 0
mov [esi], eax
mov edi, edx
sub esi, 4
loop mul1
mov [esi], edx
}
}
void __cdecl sub2array(int *array1, int *array2)
{
__asm {
mov esi, array1
mov edi, array2
mov ecx, BinLen
dec ecx
sub1: mov eax, [edi+ecx*4]
sbb [esi+ecx*4], eax
loop sub1
}
}
/////////////////////////////////////////////////////////////////////////////
// CAboutDlg dialog used for App About
class CAboutDlg : public CDialog
{
public:
CAboutDlg();
// Dialog Data
//{{AFX_DATA(CAboutDlg)
enum { IDD = IDD_ABOUTBOX };
//}}AFX_DATA
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CAboutDlg)
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
//}}AFX_VIRTUAL
// Implementation
protected:
//{{AFX_MSG(CAboutDlg)
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
{
//{{AFX_DATA_INIT(CAboutDlg)
//}}AFX_DATA_INIT
}
void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CAboutDlg)
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
//{{AFX_MSG_MAP(CAboutDlg)
// No message handlers
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CCaleDlg dialog
CCaleDlg::CCaleDlg(CWnd* pParent /*=NULL*/)
: CDialog(CCaleDlg::IDD, pParent)
{
//{{AFX_DATA_INIT(CCaleDlg)
m_Eresult = _T("");
m_number = 100;
m_shiyan = 0;
//}}AFX_DATA_INIT
// Note that LoadIcon does not require a subsequent DestroyIcon in Win32
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}
void CCaleDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CCaleDlg)
DDX_Text(pDX, IDC_EDIT1, m_Eresult);
DDX_Text(pDX, IDC_EDIT2, m_number);
DDV_MinMaxInt(pDX, m_number, 1, 10000000);
DDX_Text(pDX, IDC_EDIT3, m_shiyan);
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CCaleDlg, CDialog)
//{{AFX_MSG_MAP(CCaleDlg)
ON_WM_SYSCOMMAND()
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
ON_BN_CLICKED(IDC_ABOUT, OnAbout)
ON_BN_CLICKED(IDC_BUTTON2, OnSave)
ON_BN_CLICKED(IDC_BUTTON3, Onquickcal)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CCaleDlg message handlers
BOOL CCaleDlg::OnInitDialog()
{
CDialog::OnInitDialog();
// Add "About..." menu item to system menu.
// IDM_ABOUTBOX must be in the system command range.
ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
ASSERT(IDM_ABOUTBOX < 0xF000);
CMenu* pSysMenu = GetSystemMenu(FALSE);
if (pSysMenu != NULL)
{
CString strAboutMenu;
strAboutMenu.LoadString(IDS_ABOUTBOX);
if (!strAboutMenu.IsEmpty())
{
pSysMenu->AppendMenu(MF_SEPARATOR);
pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
}
}
// Set the icon for this dialog. The framework does this automatically
// when the application's main window is not a dialog
SetIcon(m_hIcon, TRUE); // Set big icon
SetIcon(m_hIcon, FALSE); // Set small icon
// TODO: Add extra initialization here
if(m_Eresult=="") GetDlgItem(IDC_BUTTON2)->EnableWindow(FALSE);
return TRUE; // return TRUE unless you set the focus to a control
}
void CCaleDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
if ((nID & 0xFFF0) == IDM_ABOUTBOX)
{
CAboutDlg dlgAbout;
dlgAbout.DoModal();
}
else
{
CDialog::OnSysCommand(nID, lParam);
}
}
// If you add a minimize button to your dialog, you will need the code below
// to draw the icon. For MFC applications using the document/view model,
// this is automatically done for you by the framework.
void CCaleDlg::OnPaint()
{
if (IsIconic())
{
CPaintDC dc(this); // device context for painting
SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);
// Center icon in client rectangle
int cxIcon = GetSystemMetrics(SM_CXICON);
int cyIcon = GetSystemMetrics(SM_CYICON);
CRect rect;
GetClientRect(&rect);
int x = (rect.Width() - cxIcon + 1) / 2;
int y = (rect.Height() - cyIcon + 1) / 2;
// Draw the icon
dc.DrawIcon(x, y, m_hIcon);
}
else
{
CDialog::OnPaint();
}
}
// The system calls this to obtain the cursor to display while the user drags
// the minimized window.
HCURSOR CCaleDlg::OnQueryDragIcon()
{
return (HCURSOR) m_hIcon;
}
void CCaleDlg::OnAbout()
{
// TODO: Add your control notification handler code here
CAboutDlg dlgAbout;
dlgAbout.DoModal();
}
void CCaleDlg::OnSave()
{
// TODO: Add your control notification handler code here
LPCTSTR fileext="txt files (*.txt)|*.txt||";
CFileDialog fOpen(TRUE,NULL,NULL,OFN_HIDEREADONLY |OFN_OVERWRITEPROMPT,
fileext,NULL);
if (!(fOpen.DoModal()==IDOK)) return;
CString inputpath=fOpen.GetPathName();
if(inputpath.Find( ".txt" )==-1) inputpath+=".txt"; //文件名字没有后缀加后缀
CFile file;
if (!file.Open(inputpath, CFile::modeCreate |CFile::modeReadWrite | CFile::shareExclusive))
{ ::AfxMessageBox("打开文件写失败!!",MB_OK,0);return; }
TRY
{
UpdateData(TRUE);
file.WriteHuge(m_Eresult, strlen(m_Eresult));
}
CATCH (CFileException, e)
{
THROW_LAST();
}
END_CATCH
::AfxMessageBox("保存文件成功!",MB_OK,0);
file.Close();
}
void CCaleDlg::Onquickcal()
{
// TODO: Add your control notification handler code here
DWORD TotalTime, time1, time2;
int i;
UpdateData(TRUE);
DecLen=m_number;
if ((fp=fopen(fn_status,"rt"))==NULL)
{
if (DecLen < 10) DecLen = 10;
BinLen = (int)(DecLen / log10(2) / 32) + 2;
Step = 0;
}
else
{
fscanf(fp, "%d %d %d %d %d %d %d",
&Step, &DecLen, &BinLen, &n, &sign, &NonZeroPtr, &TotalTime);
fclose(fp);
if (Step*DecLen*BinLen*n*sign*NonZeroPtr*TotalTime == 0)
{
::AfxMessageBox("打开文件失败!!",MB_OK,0);
exit(0);
}
}
arctg5 =new int[BinLen];
arctg239 =new int[BinLen];
tmp =new int[BinLen];
if (arctg5==NULL || arctg239==NULL || tmp==NULL)
{
::AfxMessageBox("分配内存失败!!",MB_OK,0);
exit(0);
}
if (Step == 0)
{
memset(arctg5, 0, BinLen*4);
memset(arctg239, 0, BinLen*4);
memset(tmp, 0, BinLen*4);
}
else
{
if ((fp=fopen(fn_arctg5,"rb"))==NULL)
{
::AfxMessageBox("打开文件写失败!!",MB_OK,0);
fclose(fp);exit(0);
}
if (fread(arctg5, 4, BinLen, fp) != (unsigned)BinLen)
{
::AfxMessageBox("打开文件读失败!!",MB_OK,0);
fclose(fp);exit(0);
}
//fclose(fp);
if ((fp=fopen(fn_arctg239,"rb"))==NULL)
{
::AfxMessageBox("打开文件写失败!!",MB_OK,0);
fclose(fp);exit(0);
}
if (fread(arctg239, 4, BinLen, fp) != (unsigned)BinLen)
{
::AfxMessageBox("打开文件读失败!!",MB_OK,0);
fclose(fp); exit(0);
}
//fclose(fp);
if ((fp=fopen(fn_tmp,"rb"))==NULL)
{
::AfxMessageBox("打开文件写失败!!",MB_OK,0);
fclose(fp);exit(0);
}
if (fread(tmp, 4, BinLen, fp) != (unsigned)BinLen)
{
::AfxMessageBox("打开文件读失败!!",MB_OK,0);
fclose(fp);exit(0);
}
}
time1=GetTickCount();
if (Step == 0)
{
x = 5;
FirstDiv(arctg5);
x = x * x;
n = 3;
sign = -1;
NonZeroPtr = 1;
arctgx(arctg5);
}
else if (Step == 1)
{
x = 5 * 5;
arctgx(arctg5);
}
if (Step == 0 || Step == 1)
{
x = 239;
FirstDiv(arctg239);
x = x * x;
n = 3;
sign = -1;
NonZeroPtr = 1;
arctgx(arctg239);
}
else
{
x = 239 * 239;
arctgx(arctg239);
}
mul_array(arctg5, 16);
mul_array(arctg239, 4);
sub2array(arctg5, arctg239);
time2=GetTickCount();
TotalTime = time2 - time1;
m_Eresult="π=3.";
char string[10];
for (i=1; i<=DecLen/9; i++) {
arctg5[0] = 0;
mul_array(arctg5, 1000000000);
sprintf(string,"%09d",arctg5[0]);
m_Eresult+=string;
if(i%7==0) m_Eresult+="\r\n";
}
tail = DecLen % 9;
p10tail = 1;
for (i=1;i<=tail;i++) p10tail *= 10;
arctg5[0] = 0;
mul_array(arctg5, p10tail);
sprintf(string,"%0*d",tail,arctg5[0]);
m_Eresult+=string;
UpdateData(FALSE);
CString tell="计算完毕!\n计算时间:";
sprintf(string,"%d ms.\n",TotalTime);
tell+=string;
UpdateData(FALSE);
//delete []arctg5;
//delete []arctg239;
//delete []tmp;
if(m_Eresult=!"") GetDlgItem(IDC_BUTTON2)->EnableWindow(TRUE);
::AfxMessageBox(tell,MB_OK,0);
/*
if (_unlink(fn_status) == 0)
{
_unlink(fn_arctg5);
_unlink(fn_arctg239);
_unlink(fn_tmp);
}
*/
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -