コード例 #1
0
ファイル: agm.c プロジェクト: ProjectZeroSlackr/PiCalc
/*
** Computes the square root of 'n' by computing the reciprocal and then
** multiplying that by the original number.
** r = r*(3-n*r^2)/2
*/
void
ClassicSqrt(BigInt Root, BigInt Num, size_t Len)
{
  size_t SubLen=1;
  size_t Redo=REDO_LEN;

  {INT32 PreSet;
   double Prep;
   Prep=GetBigIntDigit(Num,0)/((double)BI_One);
   Prep=sqrt(1.0/Prep);
   PreSet=Prep*BI_One;
   SubLen=1;
   SetNum(Root,1,PreSet,0);
   ClearBigInt(Root+SubLen,Len-SubLen);
  }

  while (SubLen < Len)
    {
      SubLen *= 2;if (SubLen > Len) SubLen = Len;
      if (!Cfg.Macintosh)
        fprintf(stderr,"Sqrt: %4s",Num2Str(SubLen*RawIntDigits));

      FullMul(DSWork, Root, Root, SubLen);
      FullMul(DSWork, Num, DSWork, SubLen);
      RevSubInt(BI_Three,DSWork,SubLen);
      FullMul(Root,Root,DSWork,SubLen);
      DivBy(Root, Root, 2, SubLen);
      if (SubLen == Redo) {SubLen/=2;Redo=0;}
      if (!Cfg.Macintosh) BackSpace(10);
    }

  if (!Cfg.Macintosh) fprintf(stderr,"Sqrt: Mul");
  FullMul(Root,Num,Root,Len);
  if (!Cfg.Macintosh) BackSpace(9);
}
コード例 #2
0
ファイル: agm.c プロジェクト: ProjectZeroSlackr/PiCalc
/*
** d = a/b by computing the reciprocal of b and then multiplying
** that by a.
**
** r = r*(2-br)
** d = a * r
*/
void
ClassicDivide(BigInt D, BigInt Num, BigInt Denom, size_t Len)
{ size_t SubLen;
  size_t Redo=REDO_LEN;

  {INT32 PreSet;
   double Prep;
   Prep=(1.0*BI_One)/GetBigIntDigit(Denom,0);
   PreSet=Prep*BI_One;
   SubLen=1;
   SetNum(D,1,PreSet,0);
   ClearBigInt(D+SubLen,Len-SubLen);
  }

  while (SubLen < Len)
    {
      SubLen *= 2;if (SubLen > Len) SubLen = Len;
      if (!Cfg.Macintosh) fprintf(stderr,"Div: %4s",Num2Str(SubLen*RawIntDigits));

      FullMul(DSWork, D, Denom, SubLen);
      RevSubInt(BI_Two,DSWork,SubLen);
      FullMul(D, D, DSWork, SubLen);
      if (SubLen == Redo) {SubLen/=2;Redo=0;}
      if (!Cfg.Macintosh) BackSpace(9);
    }

  if (!Cfg.Macintosh) fprintf(stderr,"Div: Mul");
  FullMul(D, Num, D, Len);
  if (!Cfg.Macintosh) BackSpace(8);
}
コード例 #3
0
ファイル: console.cpp プロジェクト: svkaiser/TurokEX
void kexConsole::ParseKey(int c) {
    switch(c) {
        case KKEY_BACKSPACE:
            BackSpace();
            return;
        case KKEY_DELETE:
            DeleteChar();
            return;
        case KKEY_LEFT:
            MoveTypePos(0);
            return;
        case KKEY_RIGHT:
            MoveTypePos(1);
            return;
        case KKEY_PAGEUP:
            LineScroll(1);
            return;
        case KKEY_PAGEDOWN:
            LineScroll(0);
            return;
    }

    if(c >= KKEY_SPACE && c < KKEY_z) {
        if(typeStrPos >= CON_INPUT_LENGTH) {
            return;
        }

        typeStr[typeStrPos++] = inputKey.GetAsciiKey((char)c, bShiftDown);
        typeStr[typeStrPos] = '\0';
    }
}
コード例 #4
0
ファイル: TextBox.cpp プロジェクト: oranmoshe/meth
// Handle and events
void TEXTBOX::Handle(INPUT_RECORD *inpt, int i){
	switch (inpt[i].EventType)
	{
	case KEY_EVENT: // keyboard input 
	{
						KEY_EVENT_RECORD ker = inpt[i].Event.KeyEvent;
						if (ker.bKeyDown && this->focus){
							switch (ker.wVirtualKeyCode){
							case VK_BACK:
								BackSpace();
								break;
							case VK_RIGHT:
							case VK_NUMPAD6:
								MoveRight();
								break;
							case VK_LEFT:
							case VK_NUMPAD4:
								MoveLeft();
								break;
							case VK_RETURN:
								break;
							case VK_DELETE:
								Delete();
								break;
							default:
								if ((ker.wVirtualKeyCode >= 65 && ker.wVirtualKeyCode <= 90) || (ker.wVirtualKeyCode >= 97 && ker.wVirtualKeyCode <= 122) || (ker.wVirtualKeyCode >= 48 && ker.wVirtualKeyCode <= 57) || (ker.wVirtualKeyCode == 32))
									PutChar(ker.wVirtualKeyCode);
								break;
							}
						}
	}
		break;

	case MOUSE_EVENT: // mouse input 
	{
						  MOUSE_EVENT_RECORD ker = inpt[i].Event.MouseEvent;
						  if (ker.dwButtonState == FROM_LEFT_1ST_BUTTON_PRESSED){
							  if (IsClicked(ker.dwMousePosition)){
								  SetColors();
								  SetFocus(&ker.dwMousePosition);
							  }
							  else{
								  SetFocus(NULL);
							  }
						  }
	}
		break;

	case WINDOW_BUFFER_SIZE_EVENT: // scrn buf. resizing 	
		break;

	case FOCUS_EVENT:  // disregard focus events 

	case MENU_EVENT:   // disregard menu events 
		break;

	default:
		break;
	}
}
コード例 #5
0
void MainWindow::keyPressEvent(QKeyEvent *e) {
    if(e->key()==Qt::Key_1) addNumber("1");
    else if(e->key()==Qt::Key_2) addNumber("2");
    else if(e->key()==Qt::Key_3) addNumber("3");
    else if(e->key()==Qt::Key_4) addNumber("4");
    else if(e->key()==Qt::Key_5) addNumber("5");
    else if(e->key()==Qt::Key_6) addNumber("6");
    else if(e->key()==Qt::Key_7) addNumber("7");
    else if(e->key()==Qt::Key_8) addNumber("8");
    else if(e->key()==Qt::Key_9) addNumber("9");
    else if(e->key()==Qt::Key_0) addNumber("0");
    else if(e->key()==Qt::Key_Plus) addOpe("+");
    else if(e->key()==Qt::Key_Minus) addOpe("-");
    else if(e->key()==Qt::Key_Asterisk) addOpe("*");
    else if(e->key()==Qt::Key_Slash) addOpe("/");
    else if(e->key()==Qt::Key_ParenLeft) addOpe("(");
    else if(e->key()==Qt::Key_ParenRight) addOpe(")");
    else if(e->key()==Qt::Key_AsciiCircum) addOpe("^");
    else if(e->key()==Qt::Key_Period) addOpe(".");
    else if(e->key()==Qt::Key_Escape) clear();
    else if(e->key()==Qt::Key_Equal) {
        value += '=';
        getResult();
    }
    else if(e->key()==Qt::Key_Backspace) BackSpace();
}
コード例 #6
0
ファイル: agm.c プロジェクト: ProjectZeroSlackr/PiCalc
static void
InvSqrtInt(BigInt Root, INT32 INum,size_t Len)
/*
** Generic routine to compute the inverse of the square root of
** an integer.  If you need the regular form, you can easily
** do a MulBy(x,x,INum,Len); yourself
*/
{
  int Sign;
  size_t Redo=REDO_LEN;
  size_t SubLen=1;
  char Check[128];

  {double Prep;INT32 PreSet;
/* Yuck.  I hate calculating the starting value. */
   Prep=sqrt(1.0/INum);
   Prep=Prep*10000000; PreSet=Prep;
   SetNum(Root,1,PreSet,0);
   ClearBigInt(Root+SubLen,Len-SubLen);
   sprintf(Check,"%08d",PreSet);
  }

  Num1IsCached = Num2IsCached = 0;
  FlushFFTCache(0);
  while (SubLen < Len)
    {
      SubLen *= 2;if (SubLen > Len) SubLen = Len;
      if (!Cfg.Macintosh)
        fprintf(stderr,"Sqrt%d: %4s",INum,Num2Str(SubLen*RawIntDigits));
      FlushFFTCache(0);

/* Perform safety check */
      if (strncmp(GetCheckStr(Root),Check,8)!=0)
        fprintf(stderr,"** WARNING **\a\nInvSqrtInt %d may be failing.\n%s vs. %s\n",
                INum,Check,GetCheckStr(Root));

      ClearBigInt(Root+SubLen/2,SubLen/2);
      SaveNum1FFT = 30;
      if (!Cfg.Macintosh) fputc('.',stderr);
      HalfMul(DSWork, Root, Root, SubLen);
      MulBy(DSWork,DSWork,INum,SubLen);

      Sign = RevSubInt(BI_One,DSWork,SubLen);

      Num1IsCached=30;
      if (!Cfg.Macintosh) fputc('.',stderr);
      HalfMul(DSWork,Root,DSWork,SubLen);
      DivBy(DSWork,DSWork,2,SubLen);

      if (Sign) Sub(Root,Root,DSWork,SubLen);
      else      Add(Root,Root,DSWork,SubLen);

      if (Redo == ULONG_MAX) Redo = 0;
      if (SubLen == Redo) {SubLen/=2;Redo=ULONG_MAX;}
      if (!Cfg.Macintosh) BackSpace(13);
    }
 FlushFFTCache(0);
}
コード例 #7
0
ファイル: Printf.c プロジェクト: jerryfree/msp430
/****************************************************************************
* 名    称:putchar2Lcd
* 功    能:向标12864液晶设备发送一字节数据(1个ASCII字符)
* 入口参数:ch: 待发送的字符  
* 出口参数:发出的字符
* 说    明: 此函数供putchar函数调用,完成printf函数底层输出到液晶。
****************************************************************************/
int putchar2Lcd(int ch)
{
    char addr,dat;
    char changeRowFlag = 0;
    
    if (ch == '\n')         //  '\n'(回车),换行
    {
        ChangeNextRow();
        changeRowFlag = 1;
    }
    else if (ch == '\b')    // '\b' (退格)
    {
        BackSpace();
    }
    else
    {
        addr = LcdReadAddr();
        if(ch < 0x80)
        {
            LcdWriteData(ch);
        }
        else
        {
            LcdWriteData(0x20);     //写入一个空字符,根据地址判断是否为前半字
            if(addr == LcdReadAddr())   //前半字 从新写入ch字符
            {
                LcdWriteComm(addr);
                LcdWriteData(ch);
            }
            else
            {
                LcdWriteComm(addr);
                dat = LcdReadData();
                if(dat < 0x80)           //前一个字符是英文字符
                {
                    LcdWriteData(0x20);                 //空格
                }
                if((addr != LcdReadAddr()) &&               //写入的是行最后位的后半字则换行
                   (addr==0x87 || addr==0x97 || addr==0x8F || addr==0x9F))
                {
                    ChangeNextRow();
                    changeRowFlag = 1;
                }
                LcdWriteData(ch);
            }
        }
    }
    if((addr != LcdReadAddr()) &&   //写入的是行最后位的后半字则换行,且未换过行
       (changeRowFlag == 0) &&   
       (addr==0x87 || addr==0x97 || addr==0x8F || addr==0x9F))
    {
        ChangeNextRow();
    }
    return (ch);
}
コード例 #8
0
MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent)
{
    title = new QLabel("Calculator",this);
    title -> setGeometry(QRect(QPoint(100,25),QSize(200,50)));

    label = new QLabel("0",this);
    label -> setGeometry(QRect(QPoint(50,50),QSize(200,50)));

    QString inStr = "Input Path";
    inputPath = new QLineEdit(inStr,this);
    inputPath -> setGeometry(QRect(QPoint(25,375),QSize(250,50)));
    inputPath -> hide();

    QString outStr = "Output Path";
    outputPath = new QLineEdit(outStr,this);
    outputPath -> setGeometry(QRect(QPoint(25,450),QSize(250,50)));
    outputPath -> hide();

    submitButton = new QPushButton("Submit",this);
    connect(submitButton,SIGNAL(released()),this,SLOT(submitPath()));
    submitButton -> setGeometry(QRect(QPoint(100,525),QSize(100,50)));
    submitButton -> hide();

    filePath = new QPushButton("Open",this);
    connect(filePath,SIGNAL(released()),this,SLOT(fileOpeAppear()));

    hideFilePath = new QPushButton("Close",this);
    connect(hideFilePath,SIGNAL(released()),this,SLOT(fileOpeDisappear()));

    backspace = new QPushButton("backspace",this);
    connect(backspace,SIGNAL(released()),this,SLOT(BackSpace()));

    operationButton[0] = new QPushButton("=",this);
    connect(operationButton[0],SIGNAL(released()),this,SLOT(equals()));
    operationButton[1] = new QPushButton("Esc",this);
    connect(operationButton[1],SIGNAL(released()),this,SLOT(clear()));

    for (int i = 2; i<10; i++) {
        QString operations[] = {"=","ESC","+","-","×","÷","(",")",".","^"};
        operationButton[i] = new QPushButton(operations[i],this);
        connect(operationButton[i],SIGNAL(released()),this,SLOT(operationPushed()));
    }

    for (int i = 0; i<10; i++) {
        QString digit = QString::number(i);
        buttons[i] = new QPushButton(digit,this);
        connect(buttons[i],SIGNAL(released()),this,SLOT(buttonPushed()));
    }
    setGeo();
}
コード例 #9
0
ファイル: vt100.c プロジェクト: AshuDassanRepo/bcit-courses
void interpretChar(char c) {
	switch (engInfo.mode) {
		case PRINTING_MODE:
			switch (c) {
				case ASCII_ESC:
					engInfo.mode = INTERPRETING_MODE;
					break;
				case ASCII_CR:
					SetCursorPosition(ROW(TermInfo), 0);
					break;
				case ASCII_LF:
					NewLine();
					break;
				case ASCII_BS:
					BackSpace();
					break;
				case ASCII_BELL:
					Beep(750, 300);
					break;
				case 0x0F:
					// do nothing!
					break;

				default:
					PrintChar(c);
					break;
			}
			break;
		case INTERPRETING_MODE:
			engInfo.code[engInfo.codeLen] = c;
			switch (parseCode()) {
				case PARTIAL:
					engInfo.codeLen++;
					break;
				case VALID:
					resetCode();
					break;
				case INVALID:
					resetCode();
					break;
			}
	}
}
コード例 #10
0
ファイル: TextBox.cpp プロジェクト: ronbezalel/Controllers
void TextBox::KeyEventProc(KEY_EVENT_RECORD ker) {
	if (ker.bKeyDown) {
		switch (ker.wVirtualKeyCode)
		{
		case VK_LEFT:
		case VK_NUMPAD4:
			MoveLeft();
			break;
		case VK_NUMPAD6:
		case VK_RIGHT:
			MoveRight();
			break;
		case VK_BACK:
			BackSpace();
			break;
		case VK_DELETE:
			Delete();
			break;
		default:
			AddCharecter(ker.uChar.AsciiChar);
			break;
		}
	}
}
コード例 #11
0
ファイル: TextBox.cpp プロジェクト: oranmoshe/meth
// Deletes the char on the cursor position.
void TEXTBOX::Delete(){
	if (value.length() > 0){
		++this->cursor.X;
		BackSpace();
	}
}
コード例 #12
0
ファイル: agm.c プロジェクト: ProjectZeroSlackr/PiCalc
static int
ComputeClassicAGM(size_t Len, size_t MaxPasses)
{
  int Sign;
  size_t Pass;
  double Pow2;
  clock_t LoopTime,EndTime,StartTime;
  BigInt AGM_A, AGM_B, AGM_C, AGMWork;
  int Done; /* boolean */

  AGM_A = CreateBigInt(Len);
  AGM_B = CreateBigInt(Len);
  AGM_C = CreateBigInt(Len);
  AGMWork = OldRoot;

  StartTime = clock();
  Pow2 = 4.0;
  Pass = 0;

  if (!LoadData(AGM_A,AGM_B,AGM_C,NO_NUM,NO_NUM,NO_NUM,
                &StartTime,&Pow2,&Pass,Len,Cfg.PiFormulaToUse))
    {
     fprintf(stderr, "Init     : ");
     LoopTime = clock();
     SetNum(AGM_A,Len,BI_One,0);
     SetNum(AGM_C,Len,BI_OneHalf,0);
     ClassicSqrt(AGM_B,AGM_C,Len);
     SetNum(AGM_C,Len,BI_One,0);
     EndTime = clock();
     fprintf(stderr,"Time= %0.2f\n", ((double)EndTime-(double)LoopTime)
	     /CLOCKS_PER_SEC);
     DumpTimings(((double)EndTime-(double)LoopTime)
	     /CLOCKS_PER_SEC);
     if (Cfg.AlwaysSaveData)
        SaveData(AGM_A,AGM_B,AGM_C,NO_NUM,NO_NUM,NO_NUM,
                 ((double)EndTime-(double)StartTime)
	     /CLOCKS_PER_SEC,Pow2,Pass,Len,Cfg.PiFormulaToUse);
    }

/*
  DumpBigInt("AGM_A",AGM_A,Len);
  DumpBigInt("AGM_B",AGM_B,Len);
  DumpBigInt("AGM_C",AGM_C,Len);
*/

  Done=0;
  MaxPasses+=Pass;
  while ((!Done) && (Pass < MaxPasses))
    {
      fprintf(stderr, "Pass %4s: ", Num2Str(1<<(++Pass)));
      LoopTime = clock();

      if (!Cfg.Macintosh) fprintf(stderr,"AGM Part1");
      /* w = (a-b)/2 */
      Sign = Sub(AGMWork, AGM_A, AGM_B, Len);
      if (Sign) Negate(AGMWork,Len);
      DivBy(AGMWork,AGMWork, 2, Len);
      if (!Cfg.Macintosh) BackSpace(9);

      /* m = w*w */
      if (!Cfg.Macintosh) fprintf(stderr,"Sqr1");
      if (IsZero(AGMWork,Len/2)) Done=1;
      if (Done) ClearBigInt(AGMWork,Len);
      else FullMul(AGMWork, AGMWork, AGMWork, Len);
      if (!Cfg.Macintosh) BackSpace(4);

      if (!Cfg.Macintosh) fprintf(stderr,"AGM Part2");

      /* m = m* w^(J+1) */
      MulByFloat(AGMWork,Pow2,Len);
      Pow2 *= 2.0;

      /* c = c - m */
      if (Sign) Add(AGM_C, AGM_C, AGMWork, Len);
      else      Sub(AGM_C, AGM_C, AGMWork, Len);

      /* See if it's done */
      if (IsZero(AGMWork,Len-(Len/16))) Done=1;
      if (!Cfg.Macintosh) BackSpace(9);

      /* m = a*b */
      if (!Cfg.Macintosh) fprintf(stderr,"Sqr2");
      if (Pass==1) Copy(AGMWork,AGM_B,Len); /* first pass, AGM_A = 1.0 */
      else if (!Done)   /* If last iter, we can skip it. */
         FullMul(AGMWork, AGM_A, AGM_B, Len);

      /* a = (a+b)/2 */
      Add(AGM_A, AGM_A, AGM_B, Len);
      DivBy(AGM_A,AGM_A, 2, Len);
      if (!Cfg.Macintosh) BackSpace(4);

      /* b = sqrt(a*b) */
      if (!Done) /* Optimization */
          ClassicSqrt(AGM_B, AGMWork, Len);

      EndTime=clock();

/*
      DumpBigInt("AGM_A",AGM_A,Len);
      DumpBigInt("AGM_B",AGM_B,Len);
      DumpBigInt("AGM_C",AGM_C,Len);
*/
      DumpDebug("Pass %u took:", Pass);
      fprintf(stderr, "Time= %0.2f\n", ((double)EndTime-(double)LoopTime)
	     /CLOCKS_PER_SEC);
      DumpTimings(((double)EndTime-(double)LoopTime)
	     /CLOCKS_PER_SEC);

      if (TestKeyboard()) break;
     if (Cfg.AlwaysSaveData)
        SaveData(AGM_A,AGM_B,AGM_C,NO_NUM,NO_NUM,NO_NUM,
                 ((double)EndTime-(double)StartTime)
	     /CLOCKS_PER_SEC,Pow2,Pass,Len,Cfg.PiFormulaToUse);
    }

  LoopTime=clock();
  if (Done)
    {
     fprintf(stderr,"Final    : ");
     if (!Cfg.Macintosh) fprintf(stderr,"Sqr");
     FullMul(AGM_A, AGM_A, AGM_A, Len);
     MulBy(AGM_A,AGM_A,4,Len);
     if (!Cfg.Macintosh) BackSpace(3);

     ClassicDivide(AGM_B, AGM_A, AGM_C,Len);
     EndTime=clock();
     fprintf(stderr, "Time= %0.2f\n", ((double)EndTime-(double)LoopTime)
	     /CLOCKS_PER_SEC);
     DumpTimings(((double)EndTime-(double)LoopTime)
	     /CLOCKS_PER_SEC);
     PrintFormattedPi("Classic AGM",((double)EndTime-(double)StartTime)
	     /CLOCKS_PER_SEC, AGM_B, Len);
     DeleteSaveFile();
    }
  else if (Pass >= FatalPasses)
       FatalError("The AGM didn't converge.\n");
  else SaveData(AGM_A,AGM_B,AGM_C,NO_NUM,NO_NUM,NO_NUM,
                ((double)clock()-(double)StartTime)
	     /CLOCKS_PER_SEC,Pow2,Pass,Len,Cfg.PiFormulaToUse);

  fprintf(stderr,"\nTotal Execution time: %0.2f seconds.\n\n",((double)clock()-(double)StartTime)
	     /CLOCKS_PER_SEC);
  if (!Done) DumpTimings(((double)clock()-(double)StartTime)
	     /CLOCKS_PER_SEC);

  return (Done);
}
コード例 #13
0
ファイル: SKKTextBuffer.cpp プロジェクト: 0xBADDCAFE/aquaskk
void SKKTextBuffer::Delete() {
    if(cursor_ != maxCursorPosition()) {
	CursorRight();
	BackSpace();
    }
}
コード例 #14
0
ファイル: agm.c プロジェクト: ProjectZeroSlackr/PiCalc
/*
*****************************************************
**      The AGM itself                             **
**                                                 **
** A[n] = (A[n-1] + B[n-1])/2                      **
** B[n] = Sqrt(A[n-1]*B[n-1])                      **
** C[n] = (A[n-1]-B[n-1])/2                        **
**                                                 **
**                          n                      **
** PI[n] = 4A[n+1]^2 / (1-(Sum (2^(j+1))*C[j]^2))  **
**                        j = 1                    **
*****************************************************
*/
static int
ComputeSlowAGM(size_t Len, size_t MaxPasses)
{
  int Sign;
  size_t Pass;
  double Pow2;
  clock_t LoopTime,StartTime,EndTime;
  BigInt AGM_A, AGM_B, AGM_C, AGMWork;
  int Done; /* boolean */

  if ((Cfg.PiFormulaToUse != 2) && (Cfg.PiFormulaToUse != 3))
    FatalError("SlowAGM was somehow called with pi formula %d\n",
               Cfg.PiFormulaToUse);

  AGM_A = CreateBigInt(Len);
  AGM_B = CreateBigInt(Len);
  AGM_C = CreateBigInt(Len);
  AGMWork = CreateBigInt(Len);

  Num1IsCached = Num2IsCached = 0;
  StartTime = clock();
  Pow2 = 4.0;
  Pass = 0;

  if (!LoadData(AGM_A,AGM_B,AGM_C,OldRoot,NO_NUM,NO_NUM,
                &StartTime,&Pow2,&Pass,Len,Cfg.PiFormulaToUse))
    {
     LoopTime = clock();
     fprintf(stderr, "Init     : ");

     if (Cfg.PiFormulaToUse==2)
       {
        SetNum(AGM_A,Len,BI_One,0);
        SetNum(AGM_C,Len,BI_One,0);
        ClearBigInt(OldRoot,Len);
        Sqrt05(AGM_B,Len);
       }
     else
       {
        Sqrt20(AGM_A,Len);
        Sqrt60(AGM_C,Len);
        if (!Cfg.Macintosh) fprintf(stderr,"Square");
        Add(AGM_B,AGM_A,AGM_C,Len);
        DivBy(AGM_B,AGM_B,4,Len);
        if (!Cfg.Macintosh) BackSpace(6);
        if (!Cfg.Macintosh) fprintf(stderr,"Setting vars");
        ClearBigInt(OldRoot,Len);
        SetNum(AGM_A,Len,BI_One,0);
        SetNum(AGM_C,Len,BI_One,0);
        if (!Cfg.Macintosh) BackSpace(12);
        Pass=1;
       }

     EndTime = clock();
     fprintf(stderr,"Time= %0.2f\n", ((double)EndTime-(double)LoopTime)
	     /CLOCKS_PER_SEC);
     DumpTimings(((double)EndTime-(double)LoopTime)
	     /CLOCKS_PER_SEC);
     if (Cfg.AlwaysSaveData)
        SaveData(AGM_A,AGM_B,AGM_C,OldRoot,NO_NUM,NO_NUM,
                 ((double)EndTime-(double)StartTime)
     /CLOCKS_PER_SEC,Pow2,Pass,Len,Cfg.PiFormulaToUse);
    }

/*
  DumpBigInt("AGM_A",AGM_A,Len);
  DumpBigInt("AGM_B",AGM_B,Len);
  DumpBigInt("AGM_C",AGM_C,Len);
*/

  Done=0;
  MaxPasses+=Pass;
  while ((!Done) && (Pass < MaxPasses))
    {
      fprintf(stderr, "Pass %4s: ", Num2Str(1<<(++Pass)));
      LoopTime = clock();

      if (!Cfg.Macintosh) fprintf(stderr,"AGM Part1");
      /* w = (a-b)/2 */
      Sign = Sub(AGMWork, AGM_A, AGM_B, Len);
      if (Sign) Negate(AGMWork,Len);
      DivBy(AGMWork,AGMWork, 2, Len);

      {size_t Nz;
       Nz=FindFirstNonZero(AGMWork,Len);
       if ((Pass > 4) && (Nz != Len))
         if ((1<<(Pass-4)) > Nz)
           fprintf(stderr,"AGMCheck1 fails.  Predicted: %lu Actual: %lu\a\n",
                   (unsigned long)1<<(Pass-4),(ULINT)Nz);
      }
      if (!Cfg.Macintosh) BackSpace(9);

      /* m = w*w */
      if (!Cfg.Macintosh) fprintf(stderr,"Sqr1");
      if (IsZero(AGMWork,Len/2)) Done=1;
      if (Done) ClearBigInt(AGMWork,Len);
      else FullMul(AGMWork, AGMWork, AGMWork, Len);
      if (!Cfg.Macintosh) BackSpace(4);

      if (!Cfg.Macintosh) fprintf(stderr,"AGM Part2");
      {size_t Nz;
      Nz=FindFirstNonZero(AGMWork,Len);
      if ((Pass > 3) && (Nz != Len))
        if ((1<<(Pass-3)) > Nz)
          fprintf(stderr,"AGMCheck2 fails.  Predicted: %lu Actual: %lu\a\n",
                  (unsigned long)1<<(Pass-3),(ULINT)Nz);
      }

      /* m = m* w^(J+1) */
      MulByFloat(AGMWork,Pow2,Len);
      Pow2 *= 2.0;

      /* c = c - m */
      if (Sign) Add(AGM_C, AGM_C, AGMWork, Len);
      else      Sub(AGM_C, AGM_C, AGMWork, Len);

      /* See if it's done */
      if (IsZero(AGMWork,Len-(Len/16))) Done=1;
      if (!Cfg.Macintosh) BackSpace(9);

      /* m = a*b */
      if (!Cfg.Macintosh) fprintf(stderr,"Sqr2");
      if (Pass==1) Copy(AGMWork,AGM_B,Len); /* first pass, AGM_A = 1.0 */
      else if (!Done)   /* If last iter, we can skip it. */
         FullMul(AGMWork, AGM_A, AGM_B, Len);
      if (!Cfg.Macintosh) BackSpace(4);

      /* a = (a+b)/2 */
      Add(AGM_A, AGM_A, AGM_B, Len);
      DivBy(AGM_A,AGM_A, 2, Len);

      /* b = sqrt(a*b) */
      if (!Done) /* Optimization */
          AGMSqrt(AGM_B, AGMWork, Len, (Pass>5) ? (2<<(Pass-5)) : 0 );

      EndTime=clock();

/*
      DumpBigInt("AGM_A",AGM_A,Len);
      DumpBigInt("AGM_B",AGM_B,Len);
      DumpBigInt("AGM_C",AGM_C,Len);
*/
      DumpDebug("Pass %u took:", Pass);
      fprintf(stderr, "Time= %0.2f\n", ((double)EndTime-(double)LoopTime)
     /CLOCKS_PER_SEC);
      DumpTimings(((double)EndTime-(double)LoopTime)
	     /CLOCKS_PER_SEC);

      if (TestKeyboard()) break;
     if (Cfg.AlwaysSaveData)
        SaveData(AGM_A,AGM_B,AGM_C,OldRoot,NO_NUM,NO_NUM,
                 ((double)EndTime-(double)StartTime)
	     /CLOCKS_PER_SEC,Pow2,Pass,Len,Cfg.PiFormulaToUse);
    }

  LoopTime=clock();
  if (Done)
    {
     fprintf(stderr,"Final    : ");
     if (!Cfg.Macintosh) fprintf(stderr,"Sqr");
     SpecialSquare(AGM_A, AGM_A, Len, AGMWork);
     MulBy(AGM_A,AGM_A,4,Len);
     if (!Cfg.Macintosh) BackSpace(3);

     if (Cfg.PiFormulaToUse==3)
       {
        Sqrt30(AGM_B,Len);
        if (!Cfg.Macintosh) fprintf(stderr,"Part 2");
        FullMul(AGM_C,AGM_C,AGM_B,Len);
        SubInt(AGM_C, BI_OneHalf);
        if (!Cfg.Macintosh) BackSpace(6);
       }

     AGMDivide(AGM_B, AGM_A, AGM_C, Len, AGMWork);
     EndTime=clock();
     fprintf(stderr, "Time= %0.2f\n", ((double)EndTime-(double)LoopTime)
	     /CLOCKS_PER_SEC);
     DumpTimings(((double)EndTime-(double)LoopTime)
	     /CLOCKS_PER_SEC);
     if (Cfg.PiFormulaToUse==2)
        PrintFormattedPi("Slow 1/sqrt(2) AGM",((double)EndTime-(double)StartTime)
	     /CLOCKS_PER_SEC, AGM_B, Len);
     else
        PrintFormattedPi("Slow sqrt(3) AGM",((double)EndTime-(double)StartTime)
	     /CLOCKS_PER_SEC, AGM_B, Len);
     DeleteSaveFile();
    }
  else if (Pass >= FatalPasses)
       FatalError("The AGM didn't converge.\n");
  else SaveData(AGM_A,AGM_B,AGM_C,OldRoot,NO_NUM,NO_NUM,
                ((double)clock()-(double)StartTime)
	     /CLOCKS_PER_SEC,Pow2,Pass,Len,Cfg.PiFormulaToUse);

  fprintf(stderr,"\nTotal Execution time: %0.2f seconds.\n\n",((double)clock()-(double)LoopTime)
	     /CLOCKS_PER_SEC);
  if (!Done) DumpTimings(((double)clock()-(double)LoopTime)
	     /CLOCKS_PER_SEC);

  return (Done);
}
コード例 #15
0
ファイル: agm.c プロジェクト: ProjectZeroSlackr/PiCalc
/*
**      The AGM itself
**
** A[0]=1 B[0]=1/sqrt(2) Sum=1
**
** n=1..inf
** A[n] = (A[n-1] + B[n-1])/2
** B[n] = Sqrt(A[n-1]*B[n-1])
** C[n] = (A[n-1]-B[n-1])/2    or:
** C[n]^2 = A[n]^2 - B[n]^2    or:
** C[n]^2 = 4A[n+1]*C[n+1]
** Sum  = Sum - C[n]^2*(2^(n+1))
** PI[n] = 4A[n+1]^2 / Sum
**
** However, it's not implemented that way.  We can save a full
** sized multiplication (with two numbers) by rearranging it,
** and keeping the squares of the A and B.  Also, we can do the
** first pass a little differently since A and A^2 will both be 1.
**
** A[0]=1           A[0]^2=1
** B[0]=1/sqrt(2)   B[0]^2=0.5
**
** First pass:
**
** A[1]     = (A[0] + B[0])/2
** B[1]^2   = A[0]*B[0]  ; Since A[0]==1, B[1]^2=B[0]
** C[1]^2   = ((A[0]^2+B[0]^2)/2-B[1]^2)/2
**
** Remainging passes:
**
** C[n]     = (A[n-1]-B[n-1])/2; C[n] is actually temp usage of C[n]^2
** A[n]     = A[n-1] - C[n]
** C[n]^2   = C[n]*C[n]
** B[n]^2   = (A[n-1]^2+B[n-1]^2-4C[n]^2)/2
**
** Then the rest of the formula is done the same:
**
** A[n]^2   = C[n]^2 + B[n]^2
** B[n]     = sqrt(B[n]^2)
** Sum      = Sum - C[n]^2*(2^(n+1))
**
** It is an unusual arrangment, but they are all derived directly
** from the standard AGM formulas as given by Salamin.
**
*/
static int
ComputeFastAGM(size_t Len, size_t MaxPasses)
{
  int Sign;
  size_t Pass;
  double Pow2;
  clock_t LoopTime,EndTime,StartTime;
  BigInt AGM_A, AGM_B, AGM_Sum, AGM_C2;
  BigInt AGM_A2, AGM_B2; /* Squares */
  int Done; /* boolean */

  if ((Cfg.PiFormulaToUse != 2) && (Cfg.PiFormulaToUse != 3))
    FatalError("FastAGM was somehow called with pi formula %d\n",
               Cfg.PiFormulaToUse);

  if (!Cfg.Macintosh) fprintf(stderr,"Creating vars");
  AGM_A   = CreateBigInt(Len);
  AGM_A2  = CreateBigInt(Len);
  AGM_B   = CreateBigInt(Len);
  AGM_B2  = CreateBigInt(Len);
  AGM_C2  = CreateBigInt(Len);
  AGM_Sum = CreateBigInt(Len);
  if (!Cfg.Macintosh) BackSpace(13);

  Num1IsCached = Num2IsCached = 0;
  StartTime = clock();
  Pow2 = 4.0;
  Pass = 0;
  if (!LoadData(AGM_A,AGM_A2,AGM_B,AGM_B2,AGM_Sum,OldRoot,
    &StartTime,&Pow2,&Pass,Len,Cfg.PiFormulaToUse))
    {
     fprintf(stderr, "Init     : ");
     LoopTime = clock();
     Pow2 = 4.0;
     Pass = 0;

     if (Cfg.PiFormulaToUse==2)
       {
        if (!Cfg.Macintosh) fprintf(stderr,"Setting vars");
        SetNum(AGM_A,Len,  BI_One,0);
        SetNum(AGM_A2,Len, BI_One,0);
        SetNum(AGM_B2,Len, BI_OneHalf,0);
        SetNum(AGM_Sum,Len,BI_One,0);
        ClearBigInt(OldRoot,Len);
        if (!Cfg.Macintosh) BackSpace(12);
        Sqrt05(AGM_B,Len);
        if ((Cfg.AGMSelfCheck == 3) || (Cfg.AGMSelfCheck == 4))
          {
         /* We can use OldRoot and DSWork as scratch. */
           if (!Cfg.Macintosh) fprintf(stderr,"Self Check");
           SpecialSquare(OldRoot,AGM_B,Len,DSWork);
           DoCheck(OldRoot,AGM_B2,0,Len);
           ClearBigInt(OldRoot,Len);
           if (!Cfg.Macintosh) BackSpace(10);
          }
       }
     else
       {
        Sqrt20(AGM_A,Len);
        Sqrt60(AGM_A2,Len);
        if (!Cfg.Macintosh) fprintf(stderr,"Square");
        Add(AGM_B,AGM_A,AGM_A2,Len);
        DivBy(AGM_B,AGM_B,4,Len);
        SpecialSquare(AGM_B2,AGM_B,Len,AGM_A);
        if (!Cfg.Macintosh) BackSpace(6);
        if (!Cfg.Macintosh) fprintf(stderr,"Setting vars");
        ClearBigInt(OldRoot,Len);
        SetNum(AGM_A,Len,  BI_One,0);
        SetNum(AGM_A2,Len, BI_One,0);
        SetNum(AGM_Sum,Len,BI_One,0);
        if (!Cfg.Macintosh) BackSpace(12);
        Pass=1;
       }

     EndTime = clock();
     fprintf(stderr, "Time= %0.2f\n", ((double)EndTime-(double)LoopTime)
	     /CLOCKS_PER_SEC);
     DumpTimings(((double)EndTime-(double)LoopTime)
	     /CLOCKS_PER_SEC);
     if (Cfg.AlwaysSaveData)
        SaveData(AGM_A,AGM_A2,AGM_B,AGM_B2,AGM_Sum,OldRoot,
                 ((double)EndTime-(double)StartTime)/CLOCKS_PER_SEC,
	  Pow2,Pass,Len,Cfg.PiFormulaToUse);
    }

/*
  DumpBigInt("AGM_A  ",AGM_A,Len);
  DumpBigInt("AGM_A2 ",AGM_A2,Len);
  DumpBigInt("AGM_B  ",AGM_B,Len);
  DumpBigInt("AGM_B2 ",AGM_B2,Len);
  DumpBigInt("AGM_C2 ",AGM_C2,Len);
  DumpBigInt("AGM_Sum",AGM_Sum,Len);
*/

  Done=0;
  MaxPasses+=Pass;
  while ((!Done) && (Pass < MaxPasses))
    {size_t FNZ;
     int Key=0;
/* DJGPP stuff to test the self checking.
** Comment out the keyboard break statement at the end of the loop.
     extern int getkey(void);
     if (TestKeyboard()) {Key=getkey();srand((unsigned int)time(NULL));}
*/

      fprintf(stderr, "Pass %4s: ", Num2Str(2<<(++Pass)));
      LoopTime = clock();

      if ((Pass==1) &&
          (strcmp(GetCheckStr(AGM_A),"1000000000000000")==0))
        {
/*
** Since AGM_A==1, we can do the first pass a little differently
** and avoide the multiplication completely.
*/
         if (!Cfg.Macintosh) fprintf(stderr,"AGM Part1");

         /* Compute a=(a+b)/2 */
         if (Key=='1') CorruptVar(AGM_A,Len);
         Add(AGM_A, AGM_A, AGM_B, Len);DivBy(AGM_A,AGM_A, 2, Len);
         if (Cfg.AGMSelfCheck >= 1)
           {
            DivBy(DSWork,AGM_B,2,Len);AddInt(DSWork,BI_OneHalf);
            DoCheck(DSWork,AGM_A,1,Len);
           }

         /* Compute C^2 and B^2 */
         Add(AGM_C2,AGM_A2,AGM_B2,Len);DivBy(AGM_C2,AGM_C2,2,Len);
         if (Cfg.AGMSelfCheck >= 1) Add(DSWork,AGM_A2,AGM_B2,Len);
         Copy(AGM_B2,AGM_B,Len); /* AGM_A == 1.0, so we can copy */
         Sign=Sub(AGM_C2,AGM_C2,AGM_B2,Len);DivBy(AGM_C2,AGM_C2,2,Len);
         if (Key=='4') CorruptVar(AGM_B2,Len);
         if (Key=='5') CorruptVar(AGM_C2,Len);
         if (Sign) FatalError("AGM_C2 should never be negative.\n");
         if (!Cfg.Macintosh) BackSpace(9);
        }
      else
        {
         if (!Cfg.Macintosh) fprintf(stderr,"AGM Part1");

         /* Compute C */
/*
         Sign=Sub(AGM_C2, AGM_A, AGM_B, Len);DivBy(AGM_C2,AGM_C2,2,Len);
*/
         Sign=HalfDiff(AGM_C2,AGM_A,AGM_B,Len);
         if (Sign) FatalError("AGM_C2 should never be negative.\n");

         /* Compute A.  AGM_C2 is still only C at the moment. */
         if (Cfg.AGMSelfCheck >= 1)
           {Add(DSWork,AGM_A,AGM_B,Len);DivBy(DSWork,DSWork,2,Len);}
         if (Sub(AGM_A,AGM_A,AGM_C2,Len))
            FatalError("AGM_A should never be negative.\n");
         if (Key=='1') CorruptVar(AGM_A,Len);
         if (Cfg.AGMSelfCheck >= 1) DoCheck(DSWork,AGM_A,2,Len);

         if (!Cfg.Macintosh) BackSpace(9);
         if (!Cfg.Macintosh) fprintf(stderr,"Sqr");
         /* Compute C^2 */
         SpecialSquare(AGM_C2,AGM_C2,Len,AGM_B);
         if (Key=='5') CorruptVar(AGM_C2,Len);
         if (!Cfg.Macintosh) BackSpace(3);

         if (!Cfg.Macintosh) fprintf(stderr,"AGM Part2");
         if (Cfg.AGMSelfCheck >= 1) Add(DSWork,AGM_A2,AGM_B2,Len);
         /* Compute B^2 */
         Sign=SpecialAGMFunc1(AGM_B2,AGM_A2,AGM_C2,Len);
         if (Key=='4') CorruptVar(AGM_B2,Len);
/*
         Add(AGM_B2,AGM_B2,AGM_A2,Len);
         MulBy(AGM_A2,AGM_C2,4,Len);
         Sign=Sub(AGM_B2,AGM_B2,AGM_A2,Len);
         DivBy(AGM_B2,AGM_B2,2,Len);
*/

         if (Sign) FatalError("AGM_B2 should never be negative.\n");
         if (!Cfg.Macintosh) BackSpace(9);
        }

      if (!Cfg.Macintosh) fprintf(stderr,"AGM Part3");
      /* Compute A^2 */
      if (Cfg.AGMSelfCheck >= 1)
        {
         Add(DSWork,DSWork,AGM_B2,Len);
         Add(DSWork,DSWork,AGM_B2,Len);
         DivBy(DSWork,DSWork,4,Len);
        }
      Add(AGM_A2,AGM_C2,AGM_B2,Len);
      if (Key=='2') CorruptVar(AGM_A2,Len);
      if (Cfg.AGMSelfCheck >= 1) DoCheck(DSWork,AGM_A2,3,Len);
      if (!Cfg.Macintosh) BackSpace(9);

/*
** Do some self checking.  The estimate formula predicts the number of
** leading zeros.  It's based on the regular AGM accuracy formula.  It
** predicts just a couple of digits less than what is actually there,
** so if anything happens, this should fail.  But, since it is so
** close, it just might fail for the wrong reason.
*/
      if (!Cfg.Macintosh) fprintf(stderr,"Self Check");
      FNZ=FindFirstNonZero(AGM_C2,Len);
      if ((Pass > 3) && (FNZ != Len))
        {size_t P=Pass-2;size_t Est;
         /* formula based on the AGM 'number of digits right' formula */
         if (Cfg.PiFormulaToUse==2)
            Est=(1.364376354*(1<<(P))-P*.301029995-2.342434419)/2;
         else /* other agm does 1 less pass, so pass is one higher, so div by 4 */
            Est=(sqrt(3.0)*1.364376354*(1<<(P))-P*.301029995-2.690531961)/4;

         if (Est >= FNZ)
           {
            fprintf(stderr,"\aAGM self check fails.  Predicted: %lu Actual: %lu\n",
                    (ULINT)Est,(ULINT)FNZ);
            fprintf(stderr,"Beyond what I've tested, this may not be an actual failure\n");
            fprintf(stderr,"but an inaccuracy in the self check formula itself.\n");
           }
        }

      /* See if it's done.  (ie: more than half zeros) */
      if (FNZ > Len/2+4) Done=1;

      if ((Cfg.AGMSelfCheck == 2) || (Cfg.AGMSelfCheck == 4))
        {
      /* We can use AGM_B and DSWork as scratch. */
         SpecialSquare(AGM_B,AGM_A,Len,DSWork);
         DoCheck(AGM_B,AGM_A2,4,Len);
        }
      if (!Cfg.Macintosh) BackSpace(10);

      /* Compute B=sqrt(B^2) */
      if (!Done)
        AGMSqrt(AGM_B, AGM_B2, Len,  (Pass>5) ? (2<<(Pass-5)) : 0);
      if (Key=='3') CorruptVar(AGM_B,Len);

      if (!Cfg.Macintosh) fprintf(stderr,"AGM Part4");
      /* Sum = Sum - C2 * 2^(J+1) */
      MulByFloat(AGM_C2,Pow2,Len);Pow2 *= 2.0;
      if (Sub(AGM_Sum,AGM_Sum,AGM_C2,Len))
        FatalError("AGM_Sum should never be negative.\n");

      EndTime=clock();
/*
      DumpBigInt("AGM_A  ",AGM_A,Len);
      DumpBigInt("AGM_A2 ",AGM_A2,Len);
      DumpBigInt("AGM_B  ",AGM_B,Len);
      DumpBigInt("AGM_B2 ",AGM_B2,Len);
      DumpBigInt("AGM_C2 ",AGM_C2,Len);
      DumpBigInt("AGM_Sum",AGM_Sum,Len);
*/

      if (!Cfg.Macintosh) BackSpace(9);
      if (!Done && ((Cfg.AGMSelfCheck == 3) || (Cfg.AGMSelfCheck == 4)))
        {
      /* We can use AGM_C2 and DSWork as scratch. */
         if (!Cfg.Macintosh) fprintf(stderr,"Self Check");
         SpecialSquare(AGM_C2,AGM_B,Len,DSWork);
         DoCheck(AGM_C2,AGM_B2,5,Len);
         if (!Cfg.Macintosh) BackSpace(10);
        }

      DumpDebug("Pass %u took:", Pass);
      fprintf(stderr,"Time= %0.2f\n", ((double)EndTime-(double)LoopTime)
	     /CLOCKS_PER_SEC);
      DumpTimings(((double)EndTime-(double)LoopTime)
	     /CLOCKS_PER_SEC);

      if (Cfg.AlwaysSaveData)
        SaveData(AGM_A,AGM_A2,AGM_B,AGM_B2,AGM_Sum,OldRoot,
                 ((double)EndTime-(double)StartTime)
	     /CLOCKS_PER_SEC,Pow2,Pass,Len,Cfg.PiFormulaToUse);
      if (TestKeyboard()) break;
    }


/* We've done the AGM part, now do the final calculation. */
  LoopTime=clock();
  if (Done)
    {
     fprintf(stderr, "Final    : ");
/*
** Since AGM_A and AGM_B have converged, I can compute the AGM_A2
** by calculating AGM_B2.  That can be done like up above, except
** we don't need the 4*AGM_C2 because that will be zero.
*/
     if (!Cfg.Macintosh) fprintf(stderr,"Part 1");
     Add(AGM_B2,AGM_B2,AGM_A2,Len);
     MulBy(AGM_B2,AGM_B2,2,Len);
     if (!Cfg.Macintosh) BackSpace(6);

     if (Cfg.PiFormulaToUse==3)
       {
        if (!Cfg.Macintosh) fprintf(stderr,"Part 2");
        if (!Cfg.Macintosh) BackSpace(6);
        Sqrt30(AGM_A2,Len);
        if (!Cfg.Macintosh) fprintf(stderr,"Part 3");
        SpecialFullMul(AGM_A,AGM_Sum,AGM_A2,Len,AGM_B);
        SubInt(AGM_A, BI_OneHalf);
        Copy(AGM_Sum,AGM_A,Len);
        if (!Cfg.Macintosh) BackSpace(6);
       }

     AGMDivide(AGM_B, AGM_B2, AGM_Sum, Len, AGM_A2);

     EndTime=clock();
     fprintf(stderr, "Time= %0.2f\n", ((double)EndTime-(double)LoopTime)
	     /CLOCKS_PER_SEC);
     DumpTimings(((double)EndTime-(double)LoopTime)
	     /CLOCKS_PER_SEC);

     if (Cfg.PiFormulaToUse==2)
        PrintFormattedPi("Fast 1/sqrt(2) AGM",((double)EndTime-(double)StartTime)
	     /CLOCKS_PER_SEC, AGM_B, Len);
     else
        PrintFormattedPi("Fast sqrt(3) AGM",((double)EndTime-(double)StartTime)
	     /CLOCKS_PER_SEC, AGM_B, Len);

     DeleteSaveFile();
    }
  else if (Pass >= FatalPasses)
       FatalError("The AGM didn't converge.\n");
  else SaveData(AGM_A,AGM_A2,AGM_B,AGM_B2,AGM_Sum,OldRoot,
                ((double)clock()-(double)StartTime)
	     /CLOCKS_PER_SEC,Pow2,Pass,Len,Cfg.PiFormulaToUse);

  fprintf(stderr,"\nTotal Execution time: %0.2f\n\n",((double)clock()-(double)StartTime)
	     /CLOCKS_PER_SEC);
  if (!Done) DumpTimings(((double)clock()-(double)StartTime)
	     /CLOCKS_PER_SEC);

  return (Done);
}
コード例 #16
0
void QFormulatorEditWidget::keyPressEvent( QKeyEvent *e )
{
	switch( e->key() )
	{
    case Qt::Key_Up:
		if( e->modifiers() == Qt::NoModifier || e->modifiers() == Qt::KeypadModifier  )
			OnMoveUp();
		else if( (e->modifiers() & Qt::ControlModifier) && (e->modifiers() & Qt::ShiftModifier) )
			OnMoveCtrlShiftUp();
		else if( e->modifiers() & Qt::ShiftModifier )
			OnMoveShiftUp();
		else if( e->modifiers() & Qt::ControlModifier )
			OnMoveCtrlUp();
        return;
    case Qt::Key_Down:
		if( e->modifiers() == Qt::NoModifier || e->modifiers() == Qt::KeypadModifier  )
			OnMoveDown();
		else if( (e->modifiers() & Qt::ControlModifier) && (e->modifiers() & Qt::ShiftModifier) )
			OnMoveCtrlShiftDown();
		else if( e->modifiers() & Qt::ShiftModifier )
			OnMoveShiftDown();
		else if( e->modifiers() & Qt::ControlModifier )
			OnMoveCtrlDown();
        return;
    case Qt::Key_Left:
		if( e->modifiers() == Qt::NoModifier || e->modifiers() == Qt::KeypadModifier  )
			OnMoveLeft();
		else if( (e->modifiers() & Qt::ControlModifier) && (e->modifiers() & Qt::ShiftModifier) )
			OnMoveCtrlShiftLeft();
		else if( e->modifiers() & Qt::ShiftModifier )
			OnMoveShiftLeft();
		else if( e->modifiers() & Qt::ControlModifier )
			OnMoveCtrlLeft();
        return;
    case Qt::Key_Right:
		if( e->modifiers() == Qt::NoModifier || e->modifiers() == Qt::KeypadModifier  )
			OnMoveRight();
		else if( (e->modifiers() & Qt::ControlModifier) && (e->modifiers() & Qt::ShiftModifier) )
			OnMoveCtrlShiftRight();
		else if( e->modifiers() & Qt::ShiftModifier )
			OnMoveShiftRight();
		else if( e->modifiers() & Qt::ControlModifier )
			OnMoveCtrlRight();
        return;
	case Qt::Key_Home:
		if( e->modifiers() == Qt::NoModifier || e->modifiers() == Qt::KeypadModifier  )
			OnMoveHome();
		else if( (e->modifiers() & Qt::ControlModifier) && (e->modifiers() & Qt::ShiftModifier) )
			OnMoveCtrlShiftHome();
		else if( e->modifiers() & Qt::ShiftModifier )
			OnMoveShiftHome();
		else if( e->modifiers() & Qt::ControlModifier )
			OnMoveCtrlHome();
        return;
	case Qt::Key_End:
		if( e->modifiers() == Qt::NoModifier || e->modifiers() == Qt::KeypadModifier  )
			OnMoveEnd();
		else if( (e->modifiers() & Qt::ControlModifier) && (e->modifiers() & Qt::ShiftModifier) )
			OnMoveCtrlShiftEnd();
		else if( e->modifiers() & Qt::ShiftModifier )
			OnMoveShiftEnd();
		else if( e->modifiers() & Qt::ControlModifier )
			OnMoveCtrlEnd();
		break;
	case Qt::Key_PageUp:
		if( e->modifiers() == Qt::NoModifier || e->modifiers() == Qt::KeypadModifier  )
			OnMovePageUp();
		else if( (e->modifiers() & Qt::ControlModifier) && (e->modifiers() & Qt::ShiftModifier) )
			OnMoveCtrlShiftPageUp();
		else if( e->modifiers() & Qt::ShiftModifier )
			OnMoveShiftPageUp();
		else if( e->modifiers() & Qt::ControlModifier )
			OnMoveCtrlPageUp();
        return;
	case Qt::Key_PageDown:
		if( e->modifiers() == Qt::NoModifier || e->modifiers() == Qt::KeypadModifier  )
			OnMovePageDown();
		else if( (e->modifiers() & Qt::ControlModifier) && (e->modifiers() & Qt::ShiftModifier) )
			OnMoveCtrlShiftPageDown();
		else if( e->modifiers() & Qt::ShiftModifier )
			OnMoveShiftPageDown();
		else if( e->modifiers() & Qt::ControlModifier )
			OnMoveCtrlPageDown();
        return;
	case Qt::Key_Backspace:
		if( e->modifiers() == Qt::NoModifier )
			BackSpace();
        return;
	case Qt::Key_Delete:
		if( e->modifiers() == Qt::NoModifier || e->modifiers() == Qt::KeypadModifier )
			Delete();
        return;
    case Qt::Key_Return:
		if( e->modifiers() == Qt::NoModifier || e->modifiers() == Qt::KeypadModifier  )
		{
			rootNode()->MoveReturn();
			updateViewDocument();
			//cbFireEvent( FORMULIB_CALLBACK_ENTER, NULL, NULL );
		}
        return;
    case Qt::Key_Escape:
		if( e->modifiers() == Qt::NoModifier )
		{
			rootNode()->Escape();
			updateFormulatorWidget();
		}
        return;
	default:
		break;
	}

	if( e->matches( QKeySequence::Copy ) )
	{
		editCopy();
		return;
	}
	else if( e->matches( QKeySequence::Cut ) )
	{
		editCut();
		return;
	}
	else if( e->matches( QKeySequence::Paste ) )
	{
		editPaste();
		return;
	}
	if( e->matches( QKeySequence::Delete ) )
	{
		Delete();
		return;
	}
	else if( e->matches( QKeySequence::Undo ) )
	{
		editUndo();
		return;
	}
	else if( e->matches( QKeySequence::Redo ) )
	{
		editRedo();
		return;
	}
	else if( e->matches( QKeySequence::SelectAll ) )
	{
		editSelectAll();
	}
	else if( e->matches( QKeySequence::ZoomIn ) )
	{
		double value = qMin( scale() + DEFAULT_VIEWSCALE_STEP, DEFAULT_VIEWSCALE_MAX );
		setScale( value );
	}
	else if( e->matches( QKeySequence::ZoomOut ) )
	{
		double value = qMax( scale() - DEFAULT_VIEWSCALE_STEP, DEFAULT_VIEWSCALE_MIN );
		setScale( value );
	}
	else if( e->text().length() > 0 )
	{
		for( long i = 0; i < e->text().length(); i++ )
			rootNode()->Char( e->text().at( i ).unicode(), undoRedo() );
		updateViewDocument();
		//cbFireEvent( FORMULIB_CALLBACK_CHAR, nChar, NULL );
	}

	QFormulatorWidget::keyPressEvent( e );
}
コード例 #17
0
ファイル: agm.c プロジェクト: ProjectZeroSlackr/PiCalc
/*
** Computes the square root of 'n' by computing its reciprocal square
** root using the Newton's method, and then multiplying by the original
** number.  This is faster than doing the normal Newton 'divide & average'
** method.
*/
/* static */ void
AGMSqrt(BigInt Root, BigInt Num, size_t Len, size_t SubLen)
{
  int Sign;
  size_t Redo=REDO_LEN;

  if (SubLen <= 0) SubLen = 2;
  if (SubLen > Len) SubLen = Len;

  if      (NumIs(Num, 7071067,81186547)) SetNum(OldRoot,2,11892071,15002721);
  else if (NumIs(Num, 7177499,86377537)) SetNum(OldRoot,2,11803570,64195417);
  else if (NumIs(Num, 7177700,10976296)) SetNum(OldRoot,2,11803405,99073515);
  else if (NumIs(Num, 7177700,11046129)) SetNum(OldRoot,2,11803405,99016096);
/* The second AGM */
  else if (NumIs(Num, 9659258,26289068)) SetNum(OldRoot,2,10174852,23681446);
  else if (NumIs(Num, 9660709,46551927)) SetNum(OldRoot,2,10174087,99031044);
  else if (NumIs(Num, 9660709,49277277)) SetNum(OldRoot,2,10174087,97595956);

  else
    {
     DumpBigInt("Unknown Sqrt: ",Num,4);
     ExitPrg(EXIT_FAILURE);
    }
  ClearBigInt(OldRoot+SubLen,Len-SubLen);

  if (SubLen >= Redo) Redo=0;
  Num1IsCached = Num2IsCached = 0;
  FlushFFTCache(0);
  while (SubLen < Len/2)
    {
      SubLen *= 2;if (SubLen > Len) SubLen = Len;
      if (!Cfg.Macintosh)
        fprintf(stderr,"Sqrt: %4s",Num2Str(SubLen*RawIntDigits));
      FlushFFTCache(0);

/* Perform safety check */
      {char *Str=GetCheckStr(OldRoot);
       if ( (strcmp(Str,"1189207115002721")!=0) &&
            (strcmp(Str,"1180357064195417")!=0) &&
            (strcmp(Str,"1180340599073515")!=0) &&
            (strcmp(Str,"1180340599016096")!=0) &&

            (strcmp(Str,"1017485223681446")!=0) &&
            (strcmp(Str,"1017408799031044")!=0) &&
            (strcmp(Str,"1017408797595956")!=0)
          )
         fprintf(stderr,"** WARNING **\a\nAGMSqrt may be failing.\n%s\n",Str);
      }

      ClearBigInt(OldRoot+SubLen/2,SubLen/2);
      if (!Cfg.Macintosh) fputc('.',stderr);
      SaveNum1FFT = 20;
      HalfMul(DSWork, OldRoot, OldRoot, SubLen);
      if (SubLen == Len/2) SaveNum1FFT = 21;
      if (!Cfg.Macintosh) fputc('|',stderr);
      FullMul(DSWork, Num, DSWork, SubLen);

      Sign = RevSubInt(BI_One,DSWork,SubLen);

      Num1IsCached=20;
      if (!Cfg.Macintosh) fputc('.',stderr);
      HalfMul2(DSWork,OldRoot,DSWork,SubLen);

      if (Sign) Sub(OldRoot,OldRoot,DSWork,SubLen);
      else      Add(OldRoot,OldRoot,DSWork,SubLen);

      if (Redo == ULONG_MAX) Redo = 0;
      if (SubLen == Redo) {SubLen/=2;Redo=ULONG_MAX;}
      if (!Cfg.Macintosh) BackSpace(13);
    }

  if (!Cfg.Macintosh) fprintf(stderr,"Sqrt: %4s",Num2Str(Len*RawIntDigits));
  FlushFFTCache(21);
  if (!Cfg.Macintosh) fputc('.',stderr);
  SaveNum2FFT=20;
  Num1IsCached=21;
  HalfMul(Root, Num, OldRoot, Len);
  ClearBigInt(Root+Len/2,Len/2);
  if (!Cfg.Macintosh) fputc('.',stderr);
  HalfMul(DSWork, Root, Root, Len);

  Sign=Sub(DSWork, Num, DSWork, Len);
  if (Sign) Negate(DSWork,Len);

  Num1IsCached = 20;
  if (!Cfg.Macintosh) fputc('.',stderr);
  HalfMul2(DSWork,OldRoot,DSWork,Len);

  if (Sign) Sub(Root, Root, DSWork, Len);
  else      Add(Root, Root, DSWork, Len);

  if (!Cfg.Macintosh) BackSpace(13);
  Num1IsCached = Num2IsCached = 0;
  FlushFFTCache(0);
}
コード例 #18
0
ファイル: agm.c プロジェクト: ProjectZeroSlackr/PiCalc
/*
** d = a/b by computing the reciprocal of b and then multiplying
** that by a.
*/
void
AGMDivide(BigInt R, BigInt Num1, BigInt Num2, size_t Len, BigInt Work)
{ int Sign;
  size_t SubLen=2;
  size_t Redo=REDO_LEN;

  if      (NumIs(Num2, 9138931,62088927)) SetNum(R,Len,10942198, 7613238);
  else if (NumIs(Num2,12300397,35639667)) SetNum(R,Len, 8129818,66378456);
  else
    {
     DumpBigInt("Unknown Divisor: ",Num2,4);
     ExitPrg(EXIT_FAILURE);
    }

  if (SubLen >= Redo) Redo=0;
  Num1IsCached = Num2IsCached = 0;
  FlushFFTCache(0);
  while (SubLen < Len/2)
    {
      SubLen *= 2;if (SubLen > Len) SubLen = Len;
      if (!Cfg.Macintosh)
        fprintf(stderr,"Recip: %4s",Num2Str(SubLen*RawIntDigits));
      FlushFFTCache(0);

/* Perform safety check */
      if ( (strcmp(GetCheckStr(R),"1094219807613238")!=0) &&
           (strcmp(GetCheckStr(R),"0812981866378456")!=0) )
        fprintf(stderr,"** WARNING **\a\nAGMDivide may be failing.\n%s\n",GetCheckStr(R));

      SaveNum1FFT = 10;
      if (SubLen==Len/2) SaveNum2FFT=11;
      ClearBigInt(R+SubLen/2,SubLen/2);
      if (!Cfg.Macintosh) fputc('|',stderr);
      N1R0Mul(DSWork, R, Num2, Work,SubLen);

      Sign = RevSubInt(BI_One,DSWork,SubLen);

      Num1IsCached=10;
      if (!Cfg.Macintosh) fputc('.',stderr);
      HalfMul(DSWork,R,DSWork,SubLen);
      if (Sign) Sub(R,R,DSWork,SubLen);
      else      Add(R,R,DSWork,SubLen);

      if (Redo == ULONG_MAX) Redo=0;
      if (SubLen == Redo) {SubLen/=2;Redo=ULONG_MAX;}
      if (!Cfg.Macintosh) BackSpace(13);
    }

  if (!Cfg.Macintosh) fprintf(stderr,"Recip: %4s",Num2Str(Len*RawIntDigits));
  FlushFFTCache(11);
  ClearBigInt(R+Len/2,Len/2);
  SaveNum1FFT = 10;
  if (!Cfg.Macintosh) fputc('.',stderr);
  HalfMul(OldRoot,R,Num1,Len);

  ClearBigInt(OldRoot+Len/2,Len/2);
  Num2IsCached=11;
  if (!Cfg.Macintosh) fputc('|',stderr);
  N1R0Mul(DSWork,OldRoot,Num2,Work,Len);

  Sign=Sub(DSWork,Num1,DSWork,Len);
  if (Sign) Negate(DSWork,Len);

  Num1IsCached=10;
  if (!Cfg.Macintosh) fputc('.',stderr);
  HalfMul(DSWork,R,DSWork,Len);
  if (Sign) Sub(R,OldRoot,DSWork,Len);
  else      Add(R,OldRoot,DSWork,Len);

  if (!Cfg.Macintosh) BackSpace(14);
  Num1IsCached = Num2IsCached = 0;
  FlushFFTCache(0);
}