Exemple #1
0
/*
** 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);
}
Exemple #2
0
/*
** 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);
}
Exemple #3
0
void Flt2Str(float N, char *Str, uint8_t Prec){
	int32_t INum = N, INumT;
	uint32_t NLen = CheckNumLength(INum);

	Num2Str(INum, Str, 0);

	if(Prec == 0) {
		return;
	}

	Str[NLen] = '.';

	INumT = N*(float)FPow(10, Prec);
	INumT -= INum*FPow(10, Prec);

	Num2Str(Abs(INumT), &Str[NLen+1], 0);
}
Exemple #4
0
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);
}
void GameInst::SetupTraderDetailGUI()
{
	//create windows
	m_pTraderView = sfg::Table::Create();
	m_pSelectedTrader = NULL;

	//create table cells
	for(unsigned short i=0;i<3;i++)
	{
		//StorageSlots.push_back(sfg::Label::Create("storage slot " + Num2Str(i+1)));
		for(unsigned short j=0;j<8;j++)
		{
			TraderDetailCells.push_back(sfg::Label::Create("trader detail cell " + Num2Str(8*i + j + 1)));
			m_pTraderView->Attach(TraderDetailCells.back(), sf::Rect<sf::Uint32>(i + 1, j + 1, 1, 1));
		}
	}
}
AutoUTF	Panel::Info(WinTS::iterator cur) {
	AutoUTF	ret(L"Id:           ");
	ret += Num2Str((size_t)cur->id());
	ret += L"\n\n";
	ret += L"User name:    ";
	ret += cur->user();
	ret += L"\n\n";
	ret += L"State:        ";
	ret += ParseState(cur->state());
	ret += L"\n\n";
	ret += L"Session:      ";
	ret += cur->sess();
	ret += L"\n\n";
	ret += L"WinStation:   ";
	ret += cur->winSta();
	ret += L"\n\n";
	ret += L"Client:       ";
	ret += cur->client();
	ret += L"\n\n";
	return	ret;
}
Exemple #7
0
/*
** Do a Fast Fourier Transform based multiplication.
*/
INT32
FFTMul(BigInt Prod, BigInt Num1, BigInt Num2, size_t NumLen,
       size_t ProdLen, INT32 Scale)
/*
** Scale=0 means don't multiply by Scale.
** Scale!=0 means do multiply by Scale.  (Usually 10.)
**
** If a scaling causes a carry, that carry will be returned, else
** zero will be returned.
*/
{
  size_t x;
  size_t NumLen2 = NumLen * 2;
  size_t FFTLen2=CalcFFTLen(NumLen);
  FFT_DATA_TYPE *FFTNum2=FFTNum;
  int All16=0;INT32 ScaleCarry=0;

  if (NumLen <= 64)
    {INT32 *Buf1=(INT32*)CoreMemPtr;
     INT32 *Buf2=Buf1+NumLen;
     INT32 *DBuf=Buf2+NumLen;
     ReadNumIntoBuf(Num1,Buf1,NumLen);
     ReadNumIntoBuf(Num2,Buf2,NumLen);
     BlockClear(DBuf,DBuf+NumLen*2);
     BlockSlowMul(DBuf,Buf1,Buf2,NumLen);
     if (Scale) ScaleCarry=BlockMulBy(DBuf,DBuf,Scale,0,NumLen*2);
     WriteBufIntoNum(DBuf,Prod,ProdLen);
     return ScaleCarry;
    }

  if (FFTLen2 < 16)
    {UINT32 *Buf1=(UINT32*)CoreMemPtr;
     UINT32 *Buf2=Buf1+NumLen;
     UINT32 *DBuf=Buf2+NumLen;
     double *FFTNum1=(double*)(DBuf+NumLen*2);
     int     FFTLen=NumLen*2*2;
     double *FFTNum2=FFTNum1+FFTLen;
     ReadNumIntoBuf(Num1,Buf1,NumLen);
     ReadNumIntoBuf(Num2,Buf2,NumLen);
     BlockClear(DBuf,DBuf+NumLen*2);
     SimpleFFTMul(DBuf,Num1,Num2,NumLen,FFTLen,FFTNum1,FFTNum2);
     if (Scale) ScaleCarry=BlockMulBy(DBuf,DBuf,Scale,0,NumLen*2);
     WriteBufIntoNum(DBuf,Prod,ProdLen);
     return ScaleCarry;
    }


  if (NumLen > FFTLimit)
    {
     if (Cfg.AllowFractalMul)
       {
        FractalMul(FMWork,Num1,Num2,NumLen);
        if (Scale) ScaleCarry=MulBy(Prod,FMWork,Scale,ProdLen);
        else       Copy(Prod,FMWork,ProdLen);
        return ScaleCarry;
       }
     else
       FatalError("Somehow BigMul was called with a length (%lu) longer than FFTLimit (%lu)\n",
                  (ULINT)NumLen,(ULINT)FFTLimit);
    }

  MaxFFTError=0.0;
  if (FFTLen2*2*sizeof(FFT_DATA_TYPE) <= CoreMemAvail)
    {All16=-2;FFTNum2=FFTNum+FFTLen2;}

  if (!IsPow2(NumLen))
    FatalError("The FFT size is not a power of two\n");

  if (NumLen > MaxFFTLen/RawIntDigits)
    FatalError("Somehow FFTMul was called with a number longer than MAX_FFT_LIMIT.\n%lu %lu\n",
               (UINT32)NumLen,(UINT32)MaxFFTLen);

  if (NumLen > FFTLimit)
       FatalError("Somehow BigMul was called with a length (%lu) longer than FFTLimit (%lu)\n",
                  (ULINT)NumLen,(ULINT)FFTLimit);

  DumpDebug("FFT %s ",Num2Str(NumLen*RawIntDigits));
  StartTimer(FFTMulTime);
  FFTDisk-=DiskIOTime;
  if (Num1 == Num2)
    {int Line=0;
     if (Num1IsCached || Num2IsCached)
       Line=CheckFFTCache(Num2,NumLen,Num1IsCached + Num2IsCached,0);
     if (Line) LoadFFTFromCache(Line,FFTNum);
     else
       {
        DumpDebug("F");
        FwdTransform(FFTNum,Num2,NumLen);
        if (SaveNum2FFT || SaveNum1FFT)
          SaveFFTIntoCache(FFTNum, FFTLen2, Num2, NumLen,
                           SaveNum1FFT + SaveNum2FFT,0);
       }
     DoConvolution(FFTNum,-1,FFTLen2);
    }
  else
    {int Line1=0,Line2=0;
     if (Num1IsCached) Line1=CheckFFTCache(Num1,NumLen,Num1IsCached,0);
     if (Num2IsCached) Line2=CheckFFTCache(Num2,NumLen,Num2IsCached,0);
     if (Line1 && Line2)
       {
        DumpDebug("Caches...");
        LoadFFTFromCache(Line1,FFTNum);
        DoConvolution(FFTNum,Line2,FFTLen2);
       }
     else if (Line1)
       {
        DumpDebug("Cache...F");
        FwdTransform(FFTNum,Num2,NumLen);
        if (SaveNum2FFT)
          SaveFFTIntoCache(FFTNum,FFTLen2,Num2,NumLen, SaveNum2FFT,0);
        DoConvolution(FFTNum,Line1,FFTLen2);
       }
     else if (Line2)
       {
        DumpDebug("Cache...F");
        FwdTransform(FFTNum,Num1,NumLen);
        if (SaveNum1FFT)
          SaveFFTIntoCache(FFTNum,FFTLen2,Num1,NumLen, SaveNum1FFT,0);
        DoConvolution(FFTNum,Line2,FFTLen2);
       }
     else
       {
        if (SaveNum1FFT)
          {
           DumpDebug("F");
           FwdTransform(FFTNum,Num1,NumLen);
           Line1=SaveFFTIntoCache(FFTNum,FFTLen2,Num1,NumLen, SaveNum1FFT,0);
           if (All16) Line1=-2;
           else if (Line1==0) SaveFFTIntoCache0(FFTNum,FFTLen2);
           DumpDebug("F");
           FwdTransform(FFTNum2,Num2,NumLen);
           if (SaveNum2FFT)
             SaveFFTIntoCache(FFTNum2,FFTLen2,Num2,NumLen, SaveNum2FFT,0);
           DoConvolution(FFTNum,Line1,FFTLen2);
          }
        else if (SaveNum2FFT)
          {
           DumpDebug("F");
           FwdTransform(FFTNum,Num2,NumLen);
           Line2=SaveFFTIntoCache(FFTNum,FFTLen2,Num2,NumLen, SaveNum2FFT,0);
           if (All16) Line2=-2;
           else if (Line2==0) SaveFFTIntoCache0(FFTNum,FFTLen2);
           DumpDebug("F");
           FwdTransform(FFTNum2,Num1,NumLen);
           if (SaveNum1FFT)
             SaveFFTIntoCache(FFTNum2,FFTLen2,Num1,NumLen, SaveNum1FFT,0);
           DoConvolution(FFTNum,Line2,FFTLen2);
          }
        else
          {
           Line2=All16;
           DumpDebug("F");
           FwdTransform(FFTNum,Num1,NumLen);
           if (!All16) SaveFFTIntoCache0(FFTNum,FFTLen2);
           DumpDebug("F");
           FwdTransform(FFTNum2,Num2,NumLen);
           DoConvolution(FFTNum,Line2,FFTLen2);
          }
       }
    }

  DeleteFFTCache(0); /* get rid of the convolution file */
/*
** Now do an Inverse FFT
*/
  DumpDebug("R");
  RevTransform(FFTNum,NumLen);

  DumpDebug("Carries...");
  StartTimer(CarryTime);
  MaxFFTError=0.0;
  {FFT_DATA_TYPE Carry, Round;
   INT32 *ProdBuf=(INT32*)FixedBuf;
   size_t ProdNdx,ProdPos,ProdBufLen=FIXEDBUF_SIZE/sizeof(INT32);
   double PyramidError;
   int SF=4+(RAW_FFT_DIG*2);
   int q;

   ProdNdx=ProdBufLen;ProdPos=NumLen2;
   F_Clear(&Carry);
   F_Clear(&Round);Round.Data[SF+1]=50000000;
   for (x=0; x<FFTLen2;x++)
     {
      if (FFTNum[x].Data[0] != 0)
        fprintf(stderr,"Warning, FFT appears to be overflow. %ld %d\n",x,FFTNum[x].Data[0]);
      PyramidError=FFTNum[x].Data[SF+1]/1.0e8;
      PyramidError-=0.5;PyramidError=fabs(PyramidError);PyramidError=0.5-PyramidError;
      if (PyramidError > MaxFFTError) MaxFFTError = PyramidError;
      F_Add(&FFTNum[x],&Round,&FFTNum[x]);
      F_Add(&Carry,&FFTNum[x],&Carry);
      ProdNdx-=RAW_FFT_DIG;ProdPos-=RAW_FFT_DIG;
      for (q=RAW_FFT_DIG-1;q>=0;q--)
        {
         ProdBuf[ProdNdx+q]=Carry.Data[SF];
         F_ShiftR(&Carry);
        }
      {int z;for (z=SF+1;z<FIXPOINT_LEN;z++) Carry.Data[z]=0;}
      if (ProdNdx==0)
         {size_t z;
          if (ProdPos >= ProdLen) z=0;
          else if (ProdPos+ProdBufLen < ProdLen) z=ProdBufLen;
          else z=ProdLen-ProdPos;
          if ((Scale) && (z))
            ScaleCarry=BlockMulBy(ProdBuf,ProdBuf,Scale,ScaleCarry,z);
          if (z) WriteBufIntoNum(ProdBuf,Prod+ProdPos,z);
          ProdNdx=ProdBufLen;
         }
     }
   if (ProdNdx!=ProdBufLen)
     {size_t z;
      ProdBufLen=ProdBufLen-ProdNdx;
      if (ProdPos >= ProdLen) z=0;
      else if (ProdPos+ProdBufLen < ProdLen) z=ProdBufLen;
      else z=ProdLen-ProdPos;
      if ((Scale) && (z))
         ScaleCarry=BlockMulBy(ProdBuf+ProdNdx,ProdBuf+ProdNdx,Scale,ScaleCarry,z);
      if (z) WriteBufIntoNum(ProdBuf+ProdNdx,Prod+ProdPos,z);
     }
   StopTimer(CarryTime);
/*
   F_Clear(&Carry);
//   F_Clear(&Round);Round.Data[9]=50000000;
//   F_Clear(&Round);Round.Data[7]=50000000;
   F_Clear(&Round);Round.Data[11]=50000000;
   for (x=0; x<FFTLen2;x++)
     {
      if (FFTNum[x].Data[0] != 0)
        fprintf(stderr,"Warning, FFT appears to be overflow. %ld %d\n",x,FFTNum[x].Data[0]);
//      PyramidError=FFTNum[x].Data[9]/1.0e8;
//      PyramidError=FFTNum[x].Data[7]/1.0e8;
      PyramidError=FFTNum[x].Data[11]/1.0e8;
      PyramidError-=0.5;
      PyramidError=fabs(PyramidError);
      PyramidError=0.5-PyramidError;
      if (PyramidError > MaxFFTError) MaxFFTError = PyramidError;
      F_Add(&FFTNum[x],&Round,&FFTNum[x]);
      F_Add(&Carry,&FFTNum[x],&Carry);
//      P[x]=Carry.Data[8];
//      P[x]=Carry.Data[6];
      P[x]=Carry.Data[10];
      F_ShiftR(&Carry);
//      {int z;for (z=9;z<FIXPOINT_LEN;z++) Carry.Data[z]=0;}
//      {int z;for (z=7;z<FIXPOINT_LEN;z++) Carry.Data[z]=0;}
      {int z;for (z=11;z<FIXPOINT_LEN;z++) Carry.Data[z]=0;}
     }
   StopTimer(CarryTime);
   for (x=0;x<FFTLen2/2;x++) {UINT32 t=P[x];P[x]=P[FFTLen2-x-1];P[FFTLen2-x-1]=t;}
   if (Scale) ScaleCarry=BlockMulBy((INT32*)P,(INT32*)P,Scale,0,Min(ProdLen,NumLen2));
   WriteBufIntoNum((INT32*)P,Prod,Min(ProdLen,NumLen2));
*/
  }

  /*
  ** Do a bit of 'sanity' error checking.  This value
  ** is based on some testing with a 'test jig' and
  ** personal opinion.  Should be good enough to catch
  ** systems with poor FPUs.  However, if the value ever
  ** actually reaches 0.5, then you know for a FACT that
  ** the FFTMul() has failed.
  */
  if (MaxFFTError >= 0.2)
    {
      printf("\n**WARNING** Len=%lu Max FFT Error: %f\n",
             (ULINT)NumLen,(double)MaxFFTError);
      puts("Either the FFT is approaching its limit, or a sofware");
      puts("or hardware error occured.  This can also be caused by");
      puts("a program bug, poor trig, etc.  You may wish to lower");
      puts("the MaxFFTLen limit in fft.h and run it again.");
      ExitPrg(EXIT_FAILURE);
    }

  StopTimer(FFTMulTime);
  FFTDisk+=DiskIOTime;
  DumpDebug("Done FFT.\n");
  return ScaleCarry;
}
void GameInst::UpdateTraderDetailGUI()
{
	if(m_pSelectedTrader && m_CurView == VIEW_TRADER)
	{
		//column1
		TraderDetailCells[NAME]->SetText( "Trader name: " + m_pSelectedTrader->Name);
		TraderDetailCells[WEALTH]->SetText( "Wealth: $" + Num2Str(m_pSelectedTrader->Money));
		TraderDetailCells[DECISIVENESS]->SetText( "Decisiveness: " + Num2Str(m_pSelectedTrader->Decisiveness));
		TraderDetailCells[RISKTAKER]->SetText( "Risk Taker: " + Num2Str(m_pSelectedTrader->RiskTaker));
		TraderDetailCells[CAUTIOUS]->SetText( "Catiousness: " + Num2Str(m_pSelectedTrader->Caution));
		TraderDetailCells[AMBITIOUS]->SetText( "Ambition: " + Num2Str(m_pSelectedTrader->Ambition));
		TraderDetailCells[PRIDE]->SetText( "Pride: " + Num2Str(m_pSelectedTrader->Pride));
		TraderDetailCells[RESTLESSNESS]->SetText( "Restlessness: " + Num2Str(m_pSelectedTrader->Restlessness));
		//column2
		TraderDetailCells[SHIPNAME]->SetText( "Ship name: " + std::string( m_pSelectedTrader->MyShip.Name + " (" + GetShipTypeAsStr(m_pSelectedTrader->MyShip.MyType) + ")") );
		TraderDetailCells[FUEL]->SetText( "Fuel stores: " + Num2Str(m_pSelectedTrader->MyShip.FuelStored) + "/" + Num2Str(m_pSelectedTrader->MyShip.FuelMax));
		TraderDetailCells[STORAGE]->SetText( "Used storage space: " + Num2Str(m_pSelectedTrader->MyShip.StorageUsed) + "/" + Num2Str(m_pSelectedTrader->MyShip.StorageMax));
		TraderDetailCells[MAINTENANCE]->SetText( "Maintenance level: " + Num2Str(m_pSelectedTrader->MyShip.MaintLevel) + "/" + Num2Str(m_pSelectedTrader->MyShip.MaintMax));
		TraderDetailCells[SPEED]->SetText( "Ship speed: " + Num2Str(m_pSelectedTrader->MyShip.Speed));
		TraderDetailCells[RANGE]->SetText( "Travel range: " + Num2Str(m_pSelectedTrader->MyShip.GetRange()));
		TraderDetailCells[LOCATION]->SetText( "Current location: " + Num2Str(m_pSelectedTrader->LocationUID));
		TraderDetailCells[DESTINATION]->SetText( "Destination: " + Num2Str(m_pSelectedTrader->DestinationUID));
		//column3
		short numResources = m_pSelectedTrader->MyShip.StoredResources.size();
		for(unsigned short n=0;n<numResources;n++)
		{
			TraderDetailCells[TraderCells(n)]->SetText(GetResourceAsStr((RESOURCE_TYPE)(n+1)) + ": " + Num2Str(m_pSelectedTrader->MyShip.StoredResources[(RESOURCE_TYPE)n+1]));
		}

		/*
		m_pTraderName->SetText( "Trader name: " + m_pSelectedTrader->Name);
		m_pTraderWealth->SetText( "Wealth: $" + Num2Str(m_pSelectedTrader->Money));
		m_pDecisiveness->SetText( "Decisiveness: " + Num2Str(m_pSelectedTrader->Decisiveness));
		m_pRiskTaker->SetText( "Risk Taker: " + Num2Str(m_pSelectedTrader->RiskTaker));
		m_pCautious->SetText( "Catiousness: " + Num2Str(m_pSelectedTrader->Caution));
		m_pAmbitious->SetText( "Ambition: " + Num2Str(m_pSelectedTrader->Ambition));
		m_pPride->SetText( "Pride: " + Num2Str(m_pSelectedTrader->Pride));
		m_pRestlessness->SetText( "Restlessness: " + Num2Str(m_pSelectedTrader->Restlessness));
		//
		m_pShipName->SetText( "Ship name: " + std::string( m_pSelectedTrader->MyShip.Name + " (" + GetShipTypeAsStr(m_pSelectedTrader->MyShip.MyType) + ")") );
		m_pFuel->SetText( "Fuel stores: " + Num2Str(m_pSelectedTrader->MyShip.FuelStored) + "/" + Num2Str(m_pSelectedTrader->MyShip.FuelMax));
		m_pStorage->SetText( "Used storage space: " + Num2Str(m_pSelectedTrader->MyShip.StorageUsed) + "/" + Num2Str(m_pSelectedTrader->MyShip.StorageMax));
		m_pMaintenance->SetText( "Maintenance level: " + Num2Str(m_pSelectedTrader->MyShip.MaintLevel) + "/" + Num2Str(m_pSelectedTrader->MyShip.MaintMax));
		m_pSpeed->SetText( "Ship speed: " + Num2Str(m_pSelectedTrader->MyShip.Speed));
		m_pRange->SetText( "Travel range: " + Num2Str(m_pSelectedTrader->MyShip.GetRange()));
		m_pLocation->SetText( "Current location: " + Num2Str(m_pSelectedTrader->LocationUID));
		m_pDestination->SetText( "Destination: " + Num2Str(m_pSelectedTrader->DestinationUID));
		//
		short numResources = m_pSelectedTrader->MyShip.StoredResources.size();
		for(unsigned short n=0;n<numResources;n++)
		{
			StorageSlots[n]->SetText(GetResourceAsStr((RESOURCE_TYPE)(n+1)) + ": " + Num2Str(m_pSelectedTrader->MyShip.StoredResources[(RESOURCE_TYPE)n+1]));
		}
		for(unsigned short n=8-numResources;n<8;n++)
		{
			StorageSlots[n]->SetText("");
		}
		*/
	}
	else
	{
		for(unsigned short i=0;i<TraderDetailCells.size();i++)
		{
			TraderDetailCells[TraderCells(i)]->SetText("");
		}
		/*
		//column 1
		m_pTraderName->SetText("");
		m_pTraderWealth->SetText("");
		m_pDecisiveness->SetText("");
		m_pRiskTaker->SetText("");
		m_pCautious->SetText("");
		m_pAmbitious->SetText("");
		m_pPride->SetText("");
		m_pRestlessness->SetText("");
		//column 2
		m_pShipName->SetText("");
		m_pFuel->SetText("");
		m_pStorage->SetText("");
		m_pMaintenance->SetText("");
		m_pSpeed->SetText("");
		m_pRange->SetText("");
		m_pLocation->SetText("");
		m_pDestination->SetText("");
		//column 3
		for(unsigned short n=0;n<8;n++)
		{
			StorageSlots[n]->SetText("");
		}
		*/
	}

	//update the cells
	sfg::Container::WidgetsList cells = m_pTraderView->GetChildren();
	for(unsigned short n=0;n<cells.size();n++)
	{
		cells[n]->Update(0);
	}
}
Exemple #9
0
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);
}
Exemple #10
0
/*
*****************************************************
**      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);
}
Exemple #11
0
/*
**      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);
}
Exemple #12
0
/*
** 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);
}
Exemple #13
0
/*
** 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);
}
void GameInst::AddTraderToList(Trader* a_pTrader)
{
	TraderListItems.insert( std::pair<int, sfg::Label::Ptr>(a_pTrader->TraderUID, sfg::Label::Create(a_pTrader->Name + " (" + GetShipTypeAsStr(a_pTrader->MyShip.MyType) + "): $" + Num2Str(a_pTrader->Money)) ) );
	//TraderListItems[a_Trader.TraderUID] = sfg::Label::Create(a_Trader.Name + " (" + GetShipTypeAsStr(a_Trader.MyShip.MyType) + "): $" + Num2Str(a_Trader.Money) );
	m_pTraderList->Attach( TraderListItems[a_pTrader->TraderUID], sf::Rect<sf::Uint32>(1,TraderListItems.size(),1,1) );
	TraderListItems[a_pTrader->TraderUID]->OnLeftClick.Connect(&Trader::SelectMe, a_pTrader);
}