bool checkDoubles(double a, double b, string check)
{
if(check==">"){
if (a - b > Point / 2)return(1);elsereturn (0);
}elseif(check=="<"){
if (b - a > Point / 2)return(1);elsereturn (0);
}elseif(check==">="){
if (a - b > -Point)return(1);elsereturn (0);
}if(check=="<="){
if (b - a > -Point)return(1);elsereturn (0);
}elseif(check=="!="){
if (MathAbs(a - b) > Point / 2)return(1);elsereturn (0);
}else {
Print("Sorry you've entered a wrong check value");
}
return (0);
}
//+------------------------------------------------------------------+bool AvsB(double A, string checkStr, double B)
{
//checkStr = StringTrimLeft(StringTrimRight(checkStr));
double diff = 0.000000000000001; // 15 decimal places//double diff = 0.000000005;//double diff = 0.00000001;if (checkStr == ">" ){if (A - B > diff)return(true);elsereturn(false);}
elseif(checkStr == "<" ){if (B - A > diff)return(true);elsereturn(false);}
elseif(checkStr == ">="){if (A - B > -diff)return(true);elsereturn(false);}
elseif(checkStr == "<="){if (B - A > -diff)return(true);elsereturn(false);}
elseif(checkStr == "!="){if (MathAbs(A - B) > diff)return(true);elsereturn(false);}
elseif(checkStr == "=" || checkStr == "=="){if (MathAbs(A - B) < diff)return(true);elsereturn(false);}
else {Print("Sorry, bad usage: AvsB(A, checkStr, B). Wrong checkStr value: ",checkStr);}
return(false);
} // end of AvsB//+------------------------------------------------------------------+
Here is a check of the obvious:
if (1.34929 == NormalizeDouble(1.34929 , 5)) Alert("MT4 Pass");
elseAlert("MT4 FAIL. ROUNDOFF BUG"); // Yes, this is what MT4 does, a fail.if (AvsB(1.34929 ,"==", NormalizeDouble(1.34929 , 5))) Alert("AvsB Pass"); // It does pass using the AvsB routine!elseAlert("AvsB FAIL. ROUNDOFF BUG");
比較することができるが、内部的に A や B を正規化することができ、また比較の差(A-B や B-A の)を「桁」に基づいてより大きな数に緩和することができる、さらに別の可能なルーチンがここにあります。 このルーチンが上記の単純な「AvsB」と比べて必要であるかどうかは疑問ですが、希望に応じて使用できるように提供します。
//+------------------------------------------------------------------+bool AvsB_nA_nB_digits(double A, string checkStr, double B, bool normalizeA, bool normalizeB, int digits)
{
//checkStr = StringTrimLeft(StringTrimRight(checkStr));
if (normalizeA) A = NormalizeDouble(A,MathMin(8,digits));
if (normalizeB) B = NormalizeDouble(B,MathMin(8,digits));
double diff;
switch(digits)
{
case0 : diff = 0.5; break; // Or 1.0 ??case1 : diff = 0.1; break;
case2 : diff = 0.01; break;
case3 : diff = 0.001; break;
case4 : diff = 0.0001; break;
case5 : diff = 0.00001; break;
case6 : diff = 0.000001; break;
case7 : diff = 0.0000001; break;
case8 : diff = 0.00000001; break;
case9 : diff = 0.000000001; break;
case10 : diff = 0.0000000001; break;
case11 : diff = 0.00000000001; break;
case12 : diff = 0.000000000001; break;
case13 : diff = 0.0000000000001; break;
case14 : diff = 0.00000000000001; break;
default : diff = 0.000000000000001; break; // 15 decimal places max (I think)
}
if (checkStr == ">" ){if (A - B > diff)return(true);elsereturn(false);}
elseif(checkStr == "<" ){if (B - A > diff)return(true);elsereturn(false);}
elseif(checkStr == ">="){if (A - B > -diff)return(true);elsereturn(false);}
elseif(checkStr == "<="){if (B - A > -diff)return(true);elsereturn(false);}
elseif(checkStr == "!="){if (MathAbs(A - B) > diff)return(true);elsereturn(false);}
elseif(checkStr == "=" || checkStr == "=="){if (MathAbs(A - B) < diff)return(true);elsereturn(false);}
else {Print("Sorry, bad usage: AvsB(A, checkStr, B). Wrong checkStr value: ",checkStr);}
return(false);
} // end of AvsB_nA_nB_digits//+------------------------------------------------------------------+
比較のためであれば、自分で簡単に関数を 作ることができます。
これは単なる思いつきです。
比較のためであれば、自分で簡単に関数を作ることができます。
これは単なる思いつきです。
いい考えですね、ありがとうございます :-)
Point" や "Point/2.0" の使用は、差分値としてはあまり良いものではありません、IMO。 NormalizeDoubleで発生する丸め誤差は、8桁よりずっと小さく、15桁の可能性が高いです。
このルーチンは、まだ厳密なテストはしていませんが、(小数点以下15桁まで "diff "を使っても)うまく動作するように思われます。
Here is a check of the obvious:
比較することができるが、内部的に A や B を正規化することができ、また比較の差(A-B や B-A の)を「桁」に基づいてより大きな数に緩和することができる、さらに別の可能なルーチンがここにあります。 このルーチンが上記の単純な「AvsB」と比べて必要であるかどうかは疑問ですが、希望に応じて使用できるように提供します。
Point" や "Point/2.0" の使用は、差分値としてはあまり良いものではありません、IMO。NormalizeDoubleで発生する丸め誤差は、8桁よりはるかに小さく、15桁の可能性が高いです。
丸め誤差とみなされない最大の値、あるいは同等に、価格変化 とみなされない最小の値が欲しいところです。価格はポイントの倍数でしか変化しないので、ポイント/2はまさにそれである。
ブローカーからの2倍の値は、1.23457500000000から1.23458499999999のどこにあっても、同じ1.23458の価格とみなされるのです。
これを利用していれば、問題は起きなかったはずです。
if (a > b)
if (a >= b)
if (a != b)
normalisedoubleの使用を避けるべきでしょうか?
それともMathRound 関数 で対応できるのでしょうか?
例: double x= (MathRound( 1.37883 * 100000))/ 100000 ;
ということで、関数
*ダブルの値を含む計算で正規化ダブルを使用するだけでなく、ちょうどどこでもダブルがあります。
normalisedoubleの使用を避けるべきでしょうか?
それとも MathRound 関数で対応できるのでしょうか?
例: double x= (MathRound( 1.37883 * 100000))/ 100000 ;
あなたはまだdoubleで終わるし、まだ価格の可能性がある!
そこで、doubleをint型に変換してdoubleを比較するという解決策にたどり着きました。. .
そうすれば,....
は決して真にはならない。