가격 수 != 가격 ? - 페이지 7

 

WHRoeder: 이 코드가 좋습니까(특히 "추가됨" 및 "기본값" 확인 )? 또한 이 스레드를 방문하고 마지막 페이지로 이동하는 사람들을 위한 쉬운 최종 참조 역할을 할 수도 있습니다.

 #define LT     0
#define GT     1
#define GTE   2
#define LTE   3
#define EQ     4
#define NEQ   5

bool doublecomp( double a, int type, double b){
   // See https://forum.mql4.com/45053/page4
   // 0 compare doesn't need this function
   switch (type){
     case LT: return (b-a> Point / 2 .);
     case GT: return (a-b> Point / 2 .);
     case GTE: return (a-b>- Point ); // Added
     case LTE: return (b-a>- Point ); // Added
     case EQ: return (!( MathAbs (a-b)> Point / 2 .));
     case NEQ: return ( MathAbs (a-b)> Point / 2 .);
     default : return (- 1 ); // Added - needed to avoid compile error about not all control paths returning a value
  }
}
 

그 코드는 정확하지 않습니다.

if( !MathAbs( a - b ) > Point/2) 를 사용하여 동등성을 비교하려면 어떻게 해야 합니까? 그것은 당신에게 1.4999 == 1.5000을 알려줄 것입니다

 
SDC : if( !MathAbs( a - b ) > Point/2) 를 사용하여 동등성을 비교하려면 어떻게 해야 합니까? 그것은 당신에게 1.4999 == 1.5000을 알려줄 것입니다
  1. 그렇지 않다
    if ( ! ( MathAbs ( a     -  b    ) > Point / 2 ) ) be used to compare for equality? That would tell you 1.4999 == 1.5000
    if ( ! ( MathAbs ( 1.4999 - 1.5000   > 0.00005   )
    if ( ! ( 0.0001                    > 0.00005   )
    if ( ! ( true                                 )
    if ( false                                   ) 1.4999 is NOT equal to 1.5000
  2. 그리고 PM에서 Roel13 에게 GEQ/LEQ가 -Point /2 여야 한다고 지적했지만 그는 게시물을 편집하지 않았습니다.
  3. 그리고 이전에 게시한 것처럼 평등/비평등이 중요한 경우에만 그런 넌센스에 대해 걱정하면 됩니다. 양초의 고점 위에서 열리려면 (반올림 때문에) 양초가 정확히 고점에서 발동할 수 있는지 여부가 중요합니까? 그렇지 않은 경우 입찰가 > 높음[] 을 사용하십시오.
 

나는 사용한다

 if ( NormalizeDouble (price1-price2, Digits )== 0 )


또는 실제 가격이 아닌 두 배의 경우 더 높은 정밀도

 if ( NormalizeDouble (value1-value2, 8 )== 0 )
 
SDC : 나는 사용한다
 if ( NormalizeDouble (price1-price2, Digits )== 0 )
첫 번째 게시물을 읽으면 왜 그것이 좋은 생각이 아닌지 알게 될 것입니다.
 

Raptors는 이 코드에 대해 게시합니다.

 double TestValue = iClose ( NULL , 0 , 0 );
   
if (TestValue != NormalizeDouble (TestValue, Digits ) ) //not equal

그래서 사용한다면,

 double TestValue = iClose ( NULL , 0 , 0 );

if(NormalizeDouble(TestValue - iClose(NULL,0,0),Digits)==0) // they are considered equal

다양한 방법으로 해당 방법을 테스트했는데 예상하거나 원하는 결과를 반환하지 않는 시나리오를 찾지 못했습니다.
 

최종 코드... 감사합니다. WHRoeder

 #define LT     0
#define GT     1
#define GTE   2
#define LTE   3
#define EQ     4
#define NEQ   5

bool ComparePrice( double a, int type, double b){
   // See https://forum.mql4.com/45053/page4
   // 0 compare doesn't need this function
   switch (type){
     case LT: return (b-a> Point / 2 .);
     case GT: return (a-b> Point / 2 .);
     case GTE: return (a-b>-Point/2.);
    case LTE: return (b-a>-Point/2.);
    case EQ: return (!( MathAbs (a-b)> Point / 2 .));
     case NEQ: return ( MathAbs (a-b)> Point / 2 .);
  }
  return (- 1 );
}


그리고 가격이 아닌 다른 모든 이중성을 비교하기 위한 보조 기능일 수도 있습니다.

 bool CompareNormal( double a, int type, double b){
   // With thanks https://forum.mql4.com/45053/page4
   // 0 compare doesn't need this function
   switch (type){
     case LT: return (b-a> 0.0000000000000000000000000000001 );
     case GT: return (a-b> 0.0000000000000000000000000000001 );
     case LTE: return (b-a>- 0.0000000000000000000000000000001 );
     case GTE: return (a-b>- 0.0000000000000000000000000000001 );
     case EQ: return (!( MathAbs (a-b)> 0.0000000000000000000000000000001 ));
     case NEQ: return ( MathAbs (a-b)> 0.0000000000000000000000000000001 );
  }
   return (- 1 );
}


비교를 위해 작은 수를 사용하는 것과 관련하여 'MQL4 참조 > 언어 기본 > 데이터 유형 > 실제 유형(double, float)'도 참조하십시오.

아마도 누군가는 지수에서 0.00...1을 더 잘 쓰는 방법을 알고 있을 것입니다.

 
Roel13 : 아마도 누군가 지수에서 0.00...1을 더 잘 쓰는 방법을 알고 있을 것입니다.
 // case LT: return(b-a>0.0000000000000000000000000000001);
// case LT: return(b-a>1.0e-30);
실수 유형(이중, 부동 소수점) 참조 - MQL4 문서
위의 예에서 엡실론의 값은 미리 정의된 상수 DBL_EPSILON보다 작을 수 없습니다. 이 상수의 값은 2.2204460492503131e-016입니다.
다시 말하지만, 같음/같지 않음 이 중요한 경우를 제외하고는 이 중 어느 것도 필요하지 않습니다. 예를 들어, 이전 고점보다 높게 시가하면 반올림으로 인해 고점에서 개장하고 싶지 않습니다.
 

그래서 잠재적으로 "// 0 비교에는 이 기능 이 필요하지 않습니다"와 관련하여 내가 발견한 흥미로운 다른 것이 있습니다.

최신 버전에만 있는 버그일 수도 있고 확실하지 않습니다. 0과 비교하면 더 이상 올바르게 작동하지 않습니다. 나는 비우호적 인 것에 의지해야했습니다.

결과=(int(결과*100)/100.0); // 해상도 2자리

0 값이 실제로 0 값으로 끝나도록 하기 위해서입니다.

WHRoeder님, 감사합니다. 더 많은 연구가 필요합니다 :)

 

나는 이 주제가 너무 많은 불필요한 복잡성을 다루고 있다고 생각합니다.

프로그래머의 삶을 가능한 한 항상 쉽게 만들도록 노력하십시오. 이중 비교가 필요한 클래스에서 정의를 작성하십시오(또는 정말로 필요한 경우 메소드를 사용하십시오).

 // add more floating point zeros if you need a higher precision
#define isZero(x) ( fabs (x) < 0.000000001 )
#define isEqual(x,y) ( fabs (x-y) < 0.000000001 )

두 개의 double을 비교해야 하는 경우 다음과 같은 조건에서 사용하십시오.

 if (isEqual(myFirstDouble, mySecondDouble))
{
   // first and second doubles are considered equal
   // do something
}

double이 0인지(또는 0에 매우 가까운지) 확인하려면 다음과 같은 조건을 사용하세요.

 if (isZero(myDouble))
{
   // myDouble is considered zero
   // do something
}


참고로, 분할에 대해 이야기하는 많은 게시물을 보았기 때문에:

캡슐화를 사용하면 일부 유틸리티 메서드에 "아웃소싱"되는 코드 비용을 잊어버리는 경향이 있습니다. 나눗셈은 계산적으로 매우 비싸다는 것을 명심하십시오! 특히, 유틸리티 클래스의 어딘가에 멋진 유틸리티 메소드로 래핑되면 지표 또는 EA의 모든 곳에서 사용하기 시작하고 그들이 수행하는 계산 단계를 오랫동안 잊어 버렸습니다. 전략 테스터 를 사용할 때 우리는 우리의 엉성함에 대해 많은 불필요한 시간을 지불합니다.

경험 법칙 : 더하기와 빼기는 곱하기와 나누기보다 훨씬 빠릅니다. 나눗셈 연산은 계산 시간이 가장 오래 걸립니다. 가능한 한 부서를 최적화 하십시오! 이 루프와 같이 분모가 고정되면 ...

 for ( int i= 0 ; i < rates_total; i++)
{
     // ...
     double fraction = someNumeratorValue / 100 ;
     // ...
}

그런 다음 분모 x를 반전된 값 1/x로 바꿉니다 .

 for ( int i= 0 ; i < rates_total; i++)
{
     // ...
     double fraction = 0.01 * someNumeratorValue; // replace a denominator with it's inverted value, if possible.
     // ...
}

또한 나눗셈의 결과가 항상 같으면 계산을 한 번 수행하고 결과를 변수에 저장하여 코드의 모든 곳(예: 루프)에서 사용할 수 있습니다.

 double tradesPerDay = totalTradesPerYear/ 365 ;

for ( int i= 0 ; i < rates_total; i++)
{
     // use precomputed tradesPerDay rather than computing the division here.
}

건배,