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

 
Alain Verleyen #:

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

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

ああ...、それならなぜ「数学的に同じ式(強調表示) 」なんて 紛らわしいことをしたのか、ユニオン

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

しかし、0.0 == -0.0なので、これが問題となり、何かに影響を与えるような状況は想像できません。

 

MQLのMin/Maxの古い機能 - 開発者が考えているように、つまり正しく機能する :-)

規格が間違っているのだ。

 
Nikolai Semko #:

ああ...、それならなぜ「数学的に同じ式(強調表示) 」が あんなに紛らわしかったのか、ユニオン

しかし、0.0 == -0.0なのだから、これが問題になるような状況は想像できない。

ゼロでなければ問題でしょう。そしてゼロでは何も影響しない。

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に設定される。

これらはieee754 フォーマットではさらに特殊なケースです。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++では同じです。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 #:

C++でも同じです。C++でも同じだ。
、書式と型を間違えただけだ。

これを試してみてください:

はい、急いでいました。科学に感謝 ))

 

EAを素早くテスターに入れる必要がある場合があります。その場合は次のようにします。

未来の日付を選択し、MEでCTRL+F5を押します。

理由: