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

📄 caledlg.cpp

📁 通过c++实现对pi的多位计算
💻 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 + -