mql5言語の特徴、微妙なニュアンスとテクニック - ページ 241

 
fxsaber #:

あなたは理解しようとしない。

背景を知れば理解できるかもしれない。でも、現状では、それが正しいように見える。

 
amrali #:

2つの金額が等しい限り、そのいずれかが有効な最小値となる。MathMin(1,1)を考えてみよう。この関数が最初の(1)を返すか、2番目の(1)を返すかは変わらない。

つまり、0.0を返しても-0.0と 変わらない。

編集:ところで、ハイライトされた2つの式は同一ではない。

私は同僚のamraliと同意見 だと思います。MathMin() というネイティブ関数があることも付け加えておきます。この関数も符号の異なるゼロは等しいと考えます。私が理解する限り、そのアルゴリズムは非常に単純です。私はそれをCustomMathMin()関数に複製した。

//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart()
   {
   double positive_zero_val, negative_zero_val;
   positive_zero_val = 0.0;
   negative_zero_val = -0.0;
   // 1) -0.0 / 0.0
   double native_min_val, custom_min_val;
   native_min_val = ::MathMin(negative_zero_val, positive_zero_val);
   custom_min_val = CustomMathMin(negative_zero_val, positive_zero_val);
   ::Print("\nArguments: -0.0, 0.0");
   ::PrintFormat("Native min value = %0.2f", native_min_val);
   ::PrintFormat("Custom min value = %0.2f", custom_min_val);
   // 2) 0.0 / -0.0
   native_min_val = ::MathMin(positive_zero_val, negative_zero_val);
   custom_min_val = CustomMathMin(positive_zero_val, negative_zero_val);
   ::Print("\nArguments: 0.0, -0.0");
   ::PrintFormat("Native min value = %0.2f", native_min_val);
   ::PrintFormat("Custom min value = %0.2f", custom_min_val);
   }
//+------------------------------------------------------------------+
//| Custom MathMin                                                   |
//+------------------------------------------------------------------+
double CustomMathMin(double  value1, double  value2)
   {
   if(value1 < value2)
      return value1;
   return value2;
   }
//+------------------------------------------------------------------+


それをログに残した:

2024.01.29 23:49:46.351 c11 (EURUSD,H1) Arguments: -0.0, 0.0
2024.01.29 23:49:46.351 c11 (EURUSD,H1) Native min value = 0.00
2024.01.29 23:49:46.351 c11 (EURUSD,H1) Custom min value = 0.00
2024.01.29 23:49:46.351 c11 (EURUSD,H1) 
2024.01.29 23:49:46.351 c11 (EURUSD,H1) Arguments: 0.0, -0.0
2024.01.29 23:49:46.351 c11 (EURUSD,H1) Native min value = -0.00
2024.01.29 23:49:46.351 c11 (EURUSD,H1) Custom min value = -0.00


2つの等しい数値から、アルゴリズムが2番目の数値を最小値とするのは簡単だ。

Документация по MQL5: Математические функции / MathMin
Документация по MQL5: Математические функции / MathMin
  • www.mql5.com
MathMin - Математические функции - Справочник MQL5 - Справочник по языку алгоритмического/автоматического трейдинга для MetaTrader 5
 
fxsaber #:

あなたは理解しようとしない。

   Print(-0.0<0.0);     // false
   Print(-0.0>0.0);     // false
   Print(-0.0<=0.0);    // true
   Print(-0.0>=0.0);    // true
   Print(-0.0==0.0);    // true

それは特別なことではない。ただの-0.0=0.0だ。

 
Nikolai Semko #:

特別なことは何もない。ただ-0.0=0.0

私はこの問題をよく知っているので、プログラミング言語の数学的に同じ関数が異なる結果を生むことを示すために、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
}
 
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
}


0.0と-0.0という数字が64ビットすべて同じでないことは明らか だ:


それでも 0.0 == -0.0

Base Convert: IEEE 754 Floating Point
  • baseconvert.com
Online IEEE 754 floating point converter and analysis. Convert between decimal, binary and hexadecimal
 
Ihor Herasko #:

<と<=の記号が違うようだが......。

同意する

 
Nikolai Semko # :


0.0と-0.0という数字において、64ビットがすべて同じでないことは明らか だ:



MathMin()が決定論的であることを期待している。つまり、2つの引数が同じであれば常に同じ結果を返す。どちらの引数が1番目か2番目かによって結果が変わることはありません。

fxsaberの言う通り、これは問題だ。

 
Alain Verleyen #:

これは、MathMin()関数が決定論的であることを期待して いる。つまり、2つの引数が同じであれば常に同じ結果を与える。そして、どちらの引数が1番目か2番目かによって結果が異なることはない...。

そしてそれは2つの数値が等しい場合、2番目の数値が返されます。上に例を示しましたが...

 
   Print(pow(0.0,0.0)); 	// 1.0
   Print(pow(-0.0,-0.0));       // 1.0
   Print(pow(-0.0,0.0));        // 1.0
   Print(pow(0.0,-0.0));        // 1.0
   Print(0.0*-0.0);             // -0.0
   Print(-0.0*-0.0);            // 0.0


それは悪いことではない。

 
Alain Verleyen #:

これは、MathMin()関数が決定論的であることを期待している。つまり、2つの引数が同じであれば常に同じ結果を与える。また、どちらの引数が1番目か2番目かによって結果が異なることもない。

fxsaberの言う通り、これは問題だ。

私の言いたいことは正しい。大規模なコードで異なる結果を得るという見つけにくい問題にぶつかる可能性がある。それが、このスレッドでコミュニティに通知した理由だ。

理由: