조금 놀랐습니다 :) 저는 수사학적 질문을 하지 않고 공유하기로 결정했습니다. - 페이지 23

 
Urain :

비트 시프트를 통해 하나(2의 배수일 필요는 없음)를 다른 것으로(2의 배수일 필요는 없음) 나누시겠습니까?

좋아, 내가 가진 것을 버리고 필요한지 아닌지 스스로 생각해 볼게.

조셉 스타인(1961):

gcd(n,0) = gcd(0,n) = n

gcd(n,n) = n

gcd(2n,2m) = 2gcd(n,m)

gcd(2n,2m + 1) = gcd(n, 2m + 1)

gcd(2n + 1, 2m) = gcd(2n + 1, m)

gcd(2n + 1, 2(n + k) + 1) = gcd(2(n + k) + 1, 2n + 1) = gcd(2n + 1, k)

--

STL 제작자 Alexander Stepanov의 Yandex 강의 2개

// GCD 계산 주제 - 두 번째 강의. 하지만 둘 다 시청/듣기를 권합니다. 멋진 강의, 똑똑한 사람, 그냥 좋습니다. 예, 유용합니다.
파일:
gcd_ru.zip  365 kb
 
MetaDriver :
비트 시프트가 있는 경우 - 어서오세요. 모듈로 나누기가 있는 경우에는 필요하지 않습니다.

연속 오프셋으로 나누기

기사 끝에 흥미로운 수치:

이 알고리즘은 (n-1)에서 최악의 경우에 실행됩니다! 여기서 n은 피제수 비트 수입니다. 결과적으로 이 알고리즘은 순차 더하기 알고리즘에 비해 8비트 숫자의 경우 최대 9배, 16비트 숫자의 경우 최대 546배의 이득을 제공합니다.

 

나는 다음과 같은 값을 얻었다.

 long gcd( long m, long n) 
{
   if (m< 0 ) m=-m; 
   if (n< 0 ) n=-n;
   if (m== 0 ) return n; 
   if (n== 0 ) return m;
   int d = 0 ;
   while ((m & 1 )== 0 && (n & 1 )== 0 ) { m >>= 1 ; n >>= 1 ; ++d; }
   while ((m & 1 )== 0 ) m >>= 1 ;
   while ((n & 1 )== 0 ) n >>= 1 ;
   while (m!=n)   //  while (true)  // старый вариант 
     if (m < n) 
    {
      n -= m;
       do   n >>= 1 ;   while ((n & 1 )== 0 );
    } 
     else        // if (n < m) это теперь без надобности
    {
      m -= n;
       do   m >>= 1 ;   while ((m & 1 )== 0 );
    } 
//    else break;  // старый вариант
     return (m <<= d);
}

제대로 작동하는 것 같습니다. 모든 구멍에서 테스트를 요청합니다.

// 수정했습니다. 더 쾌적합니다.
파일:
gcd.zip  1 kb
 

이상하게도 속도는 그다지 빨라지지 않았습니다.

2011.04.03 22:56:59 gcdSpeedTest (EURUSD,M20) 커먼 타임 GreatestCommonDivisor(random(),random()) = 7656ms; // 10000000 호출
2011.04.03 22:56:51 gcdSpeedTest (EURUSD,M20) 공통 시간 gcd(random(),random()) = 5234ms; // 10000000 호출

파일:
gcd.zip  2 kb
 
MetaDriver :

이상하게도, 그것은 훨씬 더 빨리 밝혀지지 않았습니다.

2011.04.03 22:56:59 gcdSpeedTest (EURUSD,M20) 커먼 타임 GreatestCommonDivisor(random(),random()) = 7656ms; // 10000000 호출
2011.04.03 22:56:51 gcdSpeedTest (EURUSD,M20) 공통 시간 gcd(random(),random()) = 5234ms; // 10000000 호출

나는 더 많은 차이가 있습니다. 당신의 것은 3-4 배 빠르지 만 C ++에서는 그 차이가 2-2.5 배 감소하므로 정직하게 1.5 배를 추월했다는 것을 잊지 마십시오.

 void OnStart ()
  {
//---
   int total= 1000000 ;
   long x= 2 * 3 * 5 * 7 * 9 * 11 * 13 * 17 * 19 * 21 * 23 * 29 ;
   long m= 55 *x,n= 34 *x;
   uint start= GetTickCount ();
   for ( int i= 0 ;i<total;i++)x=gcd(m,n);      
   Print ( "MetaDriver gcd time=" , GetTickCount ()-start, " x=" ,x);
   start= GetTickCount ();
   for ( int i= 0 ;i<total;i++)x=GreatestCommonDivisor(m,n); 
   Print ( "Urain       GCD time=" , GetTickCount ()-start, " x=" ,x);
  }
 2011.04 . 03 22 : 35 : 41      Черновик 30 (EURUSD,M1) Urain       GCD time= 1313 x= 1222772020470
2011.04 . 03 22 : 35 : 40      Черновик 30 (EURUSD,M1) MetaDriver  gcd time= 312 x= 1222772020470
 
Urain :

나는 더 많은 차이가 있습니다. 3~4배 빠릅니다.

그러나 C ++에서는 차이가 2-2.5배 감소하므로 솔직히 1.5배를 추월했다는 것을 잊지 마십시오 .


그리고 봅시다.

mql5의 예비 버전입니다. 우리는 버그를 찾고 함께 테스트합니다.

구조의 형태로 제작되었습니다.

 struct Rational
  {
   long               n;
   long               m;
   void ErrDZ() { Print ( "Rational error: zero-denominator!" ); }
   void Neg() { n=-n; }
   void Norm() { long d=gcd(n,m); n/=d; m/=d; if (m< 0 ) { n=-n; m=-m; } }
   void Assign( long a, long b) { if (b== 0 ) { n= 0 ; m= 1 ; ErrDZ(); } if (b< 0 ) { n=-a; m=-b; } else { n=a; m=b; } }
   void nAssign( long a, long b) { Assign(a,b); Norm(); }
   void Assign( long a) { Assign(a, 1 ); }   // {n=a;m=1;}
   void Add(Rational &a) { if (m==a.m) n+=a.n; else { n*=a.m; n+=m*a.n; m*=a.m; } }
   void nAdd(Rational &a) { Add(a); Norm(); }
   void Add( long a) { n+=a*m; }
   void nAdd( long a) { Add(a); Norm(); }
   void Sub(Rational &a) { if (m==a.m) n-=a.n; else { n*=a.m; n-=m*a.n; m*=a.m; } }
   void nSub(Rational &a) { Sub(a); Norm(); }
   void Sub( long a) { n-=a*m; }
   void nSub( long a) { Sub(a); Norm(); }
   void Mul(Rational &a) { n*=a.n; m*=a.m; }
   void nMul(Rational &a) { Mul(a); Norm(); }
   void Mul( long a) { n*=a; }
   void nMul( long a) { Mul(a); Norm(); }
   void Div(Rational &a) { n*=a.m; m*=a.n; }
   void nDiv(Rational &a) { Div(a); Norm(); }
   void Div( long a) { m*=a; }
   void nDiv( long a) { Div(a); Norm(); }
   string ToString() { return "(" + IntegerToString (n)+ "/" + IntegerToString (m)+ ")" ;}
  };

모든 작업은 후속 정규화와 함께 두 가지 형태로 수행되었습니다. 유연한 디자인을 가지고 있습니다.

오버플로 가능성이 의심되는 경우 정규화 버전을 사용하고 두려워하지 마십시오. 시간을 절약할 수 있습니다(나중에 거품이 쌓이면 정상화할 수 있음).

아카이브에 간단한 테스트가 있지만 더 세게 테스트하는 것이 바람직합니다.

파일:
 
IgorM :

ATP는 최소한 인정 - 이모티콘을 잘라 냈지만 전체 게시물을 삭제하는 사람은 누구입니까?

주제별, 학업 , 소위 "카운터"가 있다는 사실이 훌륭합니다. 분명히하고 싶지만 거래 중 자동 최적화 가능성이 있습니까?

예, 그것은 단지 프로그램일 뿐입니다. 실행하면 작동하고 최적의 매개변수를 제공합니다.
 
EMAshka 확인에서 - 가장 많을 것입니다.
 

특히 이 주제에 대해 MT5 테스터의 최신 결과를 게시했습니다(다음 업데이트 이후에는 누구나 테스트를 반복할 수 있음).

이것이 MetaTrader 5 테스터가 할 수 있는 일이며 전체 인프라 레이아웃(보고서, 차트, 결과, 시각화)에서도 가능합니다.

 
Renat :

특히 이 주제에 대해 MT5 테스터의 최신 결과를 게시했습니다(다음 업데이트 이후에는 누구나 테스트를 반복할 수 있음).

이것이 MetaTrader 5 테스터가 할 수 있는 일이며 전체 인프라 레이아웃(보고서, 차트, 결과, 시각화)에서도 가능합니다.

7개 기호, 모든 틱, 2000년 이후, 2개의 매개변수(200 * 200 옵션) - 40,000개 통과, 각 기호에 대해 하루 100개 주문.

얼마나 시간이 걸려요?

10년 소요 - 356 * 10 * 100 * 7 = 25,000,000 트랜잭션

우리는 분당 약 10 틱 걸립니다

10년 - 365 * 10 * 1440 * 10 = 기호당 52,000,000틱. 그리고 솔직히 말해서, 그들은 모든 기호에 체크 표시를 합니다. 즉, 정직하게 다른 7을 곱해야합니다. 분당 10 틱이 아닙니다. 그리고 때로는 300.


얼마나 시간이 걸려요?