mql5 언어의 특징, 미묘함 및 작업 방법 - 페이지 242

 
Alain Verleyen #:

MathMin() 함수는 결정론적일 것으로 예상합니다. 따라서 두 인수가 같을 때 항상 동일한 결과를 제공합니다. 어떤 인수가 첫 번째인지 두 번째인지에 따라 다른 결과가 나오지 않아야 합니다.

fxsaber가 맞습니다. 이것이 문제입니다.

아..., 그렇다면 왜 " 수학적으로 동일한 표현식 (강조 표시) " 과 유니온
이면 충분했는데 왜 그렇게 헷갈렸을까요?

Print(MathMin(-0.0, 0.0)); // 0.0
Print(MathMin(0.0, -0.0)); // -0.0

하지만 0.0 == -0.0이므로 이것이 문제가 될 수있는 상황을 상상할 수 없으며 전혀 영향을 미치지 않습니다.

 

개발자가 생각하는 방식, 즉 올바르게 작동합니다 :-)

잘못된 것은 표준입니다.

 
Nikolai Semko #:

아..., 그렇다면 왜 " (강조 표시된) 수학적으로 동일한 표현 " 과 유니온
으로 충분했을까요?

하지만 0.0 == -0.0이므로 이것이 문제가 될 수 있는 상황은 상상할 수 없으며 실제로는 전혀 영향을 미치지 않습니다.

0이 아니라면 문제가 될 것입니다. 그리고 0에서는 아무 영향도 미치지 않습니다.
For:

x * 0.0 = 0.0
x * -0.0 = -0.0
x + -0.0 = x
x - -0.0 = x
pow(x,-0.0) = 1
log(0.0)  // -inf
log(-0.0)  // -inf
 

C++ - -0과 0의 차이점은 무엇인가요? - 스택 오버플로




따라서 0 = -0
계산과 논리에 영향을 미치지 않는 전체 기능입니다.

What is the difference between -0 and 0?
What is the difference between -0 and 0?
  • 2010.09.14
  • Danvil Danvil 22.5k 20 20 gold badges 66 66 silver badges 90 90 bronze badges
  • stackoverflow.com
In C++, for example returns . The expression is true, but the bits are different. What is the purpose of having something like which should be but is represented differently? Is used exactly the same way as in any computations?
 
fxsaber #:

저는 이 질문에 대한 이해도가 높기 때문에 프로그래밍 언어에서 수학적으로 동일한 함수가 다른 결과를 산출한다는 것을 보여주기 위해 두 가지 버전의 MathMin을 작성했습니다.

template <typename T>
T ToType( const double Num )
{
  union UNION
  {
    T Num1;
    double Num2;
  } Union;
  
  Union.Num2 = Num;
  
  return(Union.Num1);
}

void OnStart()
{
  Print(ToType<long>(MathMin(-0.0, 0.0))); // 0
  Print(ToType<long>(MathMin(0.0, -0.0))); // -9223372036854775808
}

버그인 것 같습니다.

C++에서는 잘 작동합니다:

#include <iostream>

using namespace std;
//
template <typename T>
T ToType(const double Num)
{
    union UNION
    {
        T Num1;
        double Num2;
    } Union;
    Union.Num2 = Num;
    return(Union.Num1);
}
//
int main()
{
    double positive_zero_val, negative_zero_val;
    positive_zero_val = 0.0;
    negative_zero_val = -0.0;
    //---
    long long_negative_zero_val = ToType<long>(negative_zero_val);
    printf("\nLong negative zero = %d", long_negative_zero_val);
    cin.get();
}

콘솔에서:

Long negative zero = 0


개발자에게 전달할 질문입니다. 디버깅 창에서 Union 변수가 확장되지 않고 클릭에 전혀 반응하지 않는 것이 정상인가요?


Union.Num1 및 Union.Num2 필드는 수동으로 추가되었습니다. 적어도 이렇게 하면 값을 볼 수 있습니다...

 
string DoubleToHexadecimal(const double value)
  {
   return StringFormat("0x%.16llX", value);
  }

void OnStart()
  {
   Print(DoubleToHexadecimal(0.0) );    // 0x0000000000000000   (i.e, long integer 0)
   Print(DoubleToHexadecimal(-0.0) );   // 0x8000000000000000   (i,e, LONG_MIN -9223372036854775808)
  }
  

예상대로 작동합니다! 첫 번째 비트(비트 인덱스 0)는 -0.0으로 설정된 부호 비트입니다.

또한 ieee 754 형식에서는 좀 더 특별한 경우입니다. https://www. wikiwand.com/en/IEEE%20754#Special_values

void OnStart()
  {
   const double Nan = (double)"nan";
   const double Inf = (double)"inf";

   Print( MathMin(Nan, Inf));   // inf
   Print( MathMin(Inf, Nan));   // nan

   Print( MathMin(Nan, 0));     // 0.0
   Print( MathMin(0, Nan));     // nan
  }
 
Denis Kirichenko #:

버그인 것 같습니다.

C++에서는 정상적으로 작동합니다:

콘솔에서:

버그가 없습니다. C++에서도 마찬가지입니다.
서식과 유형에 실수를 한 것입니다.

을 사용해 보세요:

#include <iostream>

using namespace std;
//
template <typename T>
T ToType(const double Num)
{
    union UNION
    {
        T Num1;
        double Num2;
    } Union;
    Union.Num2 = Num;
    return(Union.Num1);
}
//
int main()
{
    double positive_zero_val, negative_zero_val;
    positive_zero_val = 0.0;
    negative_zero_val = -0.0;
    //---
    long long  long_negative_zero_val = ToType<long long>(negative_zero_val);
    printf("\nLong negative zero = %ll d", long_negative_zero_val);
}
 

같은 맥락에서 복식의 64비트 표현을 살펴볼 수 있습니다 https://www.mql5.com/en/code/20822

//+------------------------------------------------------------------+
//| Returns the bit representation corresponding to a double value . |
//+------------------------------------------------------------------+
long DoubleToLongBits(const double value)
  {
   union _d {double value; long bits;} dbl;
   dbl.value = value;

   return dbl.bits;
  }

또는 더 짧은 버전

long DoubleToLongBits(const double value)
  {
   union _d {double value; long bits;} dbl = { value };

   return dbl.bits;
  }
 
Nikolai Semko #:

버그가 없습니다.
서식과 유형에 실수가 있었을 뿐입니다.

을 사용해 보세요:

예, 서두르고있었습니다. 과학에 감사드립니다 ))

 

때때로 EA를 테스터에 빠르게 넣어야 할 때가 있습니다. 다음과 같이 하면 됩니다.

미래의 날짜를 선택하고 ME에서 CTRL+F5를 누릅니다.