エラー、バグ、質問 - ページ 2821

 
Igor Makanu:

正規化は丸めではない

理論やダブルの効かせ方などはA+です。NormalizeDouble アルゴリズムにエラーがあります。提起された話題は、二重の比較とは間接的にしか関係ない。

 
fxsaber:

質問を繰り返す。

写真は、正規化されていない変数nと正規化された変数mの値、そしてその違いを示しています。でも、Tバックを比べたいなら、それはお好みで。

fxsaber:

理論やダブルの効かせ方など、A+のスケールで知っています。NormalizeDouble アルゴリズムにエラーがあります。提起された話題は、二重の比較とは間接的にしか関係ない。

間違いなく、ここであのセムコの説明なしではやっていけない。
 
NormalizeDoubleは、doubleの数値に適用するある種のアルゴリズムに過ぎません。残念ながら、その中に間違いがあるのです。修正すれば、エラーは消えます。それ以外のすべての二重表現が変わることはありません。
 
fxsaber:

NormalizeDouble アルゴリズムにエラーがあります。

A100が書いていたような気がする

しかし、MQL以降の開発者はこの「機能」に固執している、残念なことに


fxsaber:
修正されれば、エラーはなくなる。
他のバグも出てきて騒がれると思います )))
 
Igor Makanu:

他のバグも出てきて騒がれると思います )))

ほぼ全員が正規化されたダブも正規化を通して比較するから、そんなことはないだろう。つまり、好きな場所に置くことができるのです。


適切な正規化を行えば、この条件では常に真となるはずです。

正規化が正しく行われているかどうかのチェックは、これだけです。それが常に真実を与えてくれるなら、何も壊れることはない。

 
fxsaber:
NormalizeDoubleは、doubleの数値に適用するある種のアルゴリズムに過ぎません。残念ながら、その中に間違いがあるのです。修正すれば、エラーは消えます。他のすべての二重代表は、結果的に変わりません。
関数がどうこうではなく、定数がコンパイラで正規化されていない(はずなのに)ことが原因だと思います。
文字列からdoubleへの変換も同様です。
 
Alexey Navoykov:
関数がどうこうではなく、定数がコンパイラで正規化されていない(はずなのに)ことが原因だと思います。
文字列からダブルへの変換も同様です。

そうすると、DLLとMQLで同じ定数が一致しません。

 
fxsaber:

そうすると、DLLとMQLで同じ定数が一致しません。

また、その通りです。また、正規化すると精度が 落ちるので、定数の正規化もやりすぎたかもしれません。
一般的に、この問題は明確な解決策を持っていないと私は考えています。 実際はそのような問題ではないのですが。
 
Alexey Navoykov:
また、その通りです。それに、正規化すると精度が 落ちるので、常に正規化するのはやり過ぎかもしれませんね。
一般にこの問題は、本質的にはそのような問題ではないのですが、私には一義的な解があるようには見えません。

現在の正規化アルゴリズムに手を加えるだけです。

 
fxsaber:

現在の正規化アルゴリズムに手を加えるだけです。

void OnStart() {
   double d1=1.79435;
   double d2=NormalizeDouble(1.79435,5);
   Print(d1==d2);
   Print(is_equal(d1,d2,_Point/2));
}
//+------------------------------------------------------------------+
bool is_equal(double d1, double d2, double e=0.000000001) {return fabs(d1-d2)<e;}

これがアルゴリズムのバグなのかどうかもわからない。
本当に、ダブルは比べものにならないですね。ただ、厳しいルールです。
あるいは、Slavaさんがおっしゃるように、イプシロンや、丸め誤魔化してintに変換しての乗算(例えば1/_Point)でも可能です。

round()、ceil()、floor()はdoubleを返すので、丸めだけは 行われない。

特に通常のものよりも動作が速いので、これを通してでも。

int Ceil (double x) {return (x-(int)x>0)?(int)x+1:(int)x;}
int Round(double x) {return (x>0)?(int)(x+0.5):(int)(x-0.5);}
int Floor(double x) {return (x>0)?(int)x:((int)x-x>0)?(int)x-1:(int)x;}

もちろん、イプシロンでより簡単に、より速く。

bool is_equal(double d1, double d2, double e=0.000000001) {return fabs(d1-d2)<e;}