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

 
Alexey Viktorov:

ただ、値がなければ必ずしも0であり、bool型 変数でなければそれに対応してfalseになるとは思わないほうがよいでしょう。boolへの明示的な変換も役に立ちません。

このようにエラーなく動作します。

正直、どこからがゼロなのか、まったく理解できません。

const double Points = TickValue[0] ? Profit / (Lots * TickValue[0] * _Point) : 0; // zero divide

TickValue[0]にはゴミが含まれています。ゼロになることも、ならないこともあります。

TickValue[0]のtrashが0でない 場合、Points = Profit / Lots * non-zero trash * _Point を計算し、それ以外の場合、TickValue[0]のtrashが0に等しければ、Pointsを0と同じにしています。

また、Lots が宣言時に 1 で初期化されている場合、Lots * 非ゼロのゴミ * _Point という 表現はどこからゼロを得るのでしょうか? Pointに0は ないのか?

 
fxsaber:

事実上、間違いは明らかです。

OK、エラーは不明です。そして、私にも再現されない。

 
TheXpert:

OK、エラーは理解できない。しかも、私に向かって再現してくれるわけではありません。

大雑把に言うと、この関数を呼ぶとゼロで除算 される可能性があります。

// Неправильно написанная функция.
double WrongFunc( const double Num )
{
  return(Num ? 1 / (0.1 * Num) : 0);
}


レポートライブラリで実際にこの問題に遭遇しました。そして、それが論理的であることに気づいたのです。

 
fxsaber:

大雑把に言うと、この関数を呼ぶとゼロによる除算が 発生することがあります。

私はボーダーダブルズでこのコードを持っていますが、クラッシュしません。

double f( const double Num )
{
  return(Num ? 1 / (0.1 * Num) : 0);
}

void OnStart()
{
  Print(f(1 e-308));  // 2019.10.28 13:02:19.457	test (USDJPY,H1) inf
}
 
TheXpert:

ボーダーダブルズでも同じコードが出ますが、クラッシュしません

#include <TypeToBytes.mqh> // https://www.mql5.com/ru/code/16280

void OnStart()
{
  double Num = 0;
  
  _W(Num) = (uchar)2;
  
  Print(WrongFunc(Num));
}
 
fxsaber:
そんなヒヤヒヤするような
 
TheXpert:
そんなクラッシュを

要約すると、ゼロでない2つのダブレットを掛けるとゼロになることがあります。そして、これは退化したケースではなく、実際に存在するケースなのです。

大雑把に言うと、戦闘用EAはこのせいで壊れる可能性がゼロとは言い切れないほど高いのです。

 
また、ゼロをチェックしても、明示的にも暗黙的にも保存されません(bool変換)。
 
TheXpert:
また、ゼロをチェックしても、明示的にも暗黙的にも保存されません(bool変換)。
  return(0.1 * Num ? 1 / (0.1 * Num) : 0);
 
fxsaber:

要約すると、ゼロでない2つのダブレットを掛けるとゼロになることがあります。そして、これは退化したケースではなく、実際に存在するケースなのです。

大雑把に言うと、戦闘用EAはこのせいで壊れる可能性がゼロとは言い切れないほど高いのです。

NaN の場合は追加でチェックする必要がありますが、このコードで動作する可能性が高いです。http://qaru.site/questions/20557/checking-if-a-double-or-float-is-nan-in-c

f != f

または CompareDoubles() の例のように精度を制限する - SBhttps://www.mql5.com/ru/docs/basis/types/double にあるようです。

理由: