MQL4マスターに質問です。ダブルコンペアについてもう一度。 - ページ 6

 
VBAG:
...
イルトロンの コードの良さは、そのコンパクトさ(余分なものは一切なく、変数まで保存されている!)です。 ...



ここで、Irtronの 提案する方法をご覧ください これは私のよりもコンパクトで高速ですが、一見したところ、2つの変数doubleを含むので怪しげです!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!?この方式では、

int ComparePrice(double a, double b, double digit)
{
     a -= b;
     b = digit;
     if (a > b)
         return (1);
     if (a < -b)
         return (-1);
     return (0);
 }



桁だけが 定数として働き、比較することができますが、同じく比較される変数aは正規化されていないダブルの ままでした疑惑を持たれるのでは?(定数とは、通常の定数、つまり「#define」や演算に関与しない変数を指します)。 また、他のブランチでは、開発者自身が、定数もダブルで比較しない方が良いと書いています!これも、NormalizeDouble(a) ! NormalizeDouble(b), !OC!- 比較演算子! すべての詳細は、定数





桁の 元のバージョンでは、そうだった b =ポイント/ 2- ここではすでに2つの非正規化された変数の2?このバリエーションは天才的だと信じたいが、まずは私の疑念を払拭してくれ!」。もしかしたら、私のバリアントにも間違いを見つけてくれる人がいるかもしれませんね。
 
gravity001:

ここで、イルトロンが 提案した方法
)を見てみましょう。
int ComparePrice(double a, double b, double digit)
{
     a -= b;
     b = digit;
     if (a > b)
         return (1);
     if (a < -b)
         return (-1);
     return (0);
 }
私は別の方法を提案しました。
もっとよく見てください。


特に、元のバージョンの代わりに 定数のそれはとても b =ポイント/ 2 だったので - ここではすでに2つの非正規化された変数の2?

どのバージョンのことでしょうか?

ノーマライゼーションについては、すでにお伝えしたとおりです。まず、なぜ それを適用するのか、そして、どこで どのように 適用するのかを教えてください。

例えば、上記の議論で成果として挙げられている14記号の精度で価格を比較するのはなぜか、ご存知でしょうか。:)私が提案した関数はComparePriceと呼ばれていることを思い出してください :)
 

Irtron писал (а):
...
私は別の方法を提案しました。
もっとよく見てください。
...

どのバージョンのことでしょうか?

ノーマライゼーションについては、すでにお伝えしたとおりです。まず、なぜ それを適用すべきなのか、そして、どこで どのように 適用するのかを教えてください。

例えば、上記の議論において、ある種の成果として挙げられている14桁の精度で価格を比較しなければならない理由をご存知でしょうか?:)私が提案した関数はComparePriceと呼ばれていることを思い出してください :)
これ、あなたの?今、私は正しく引用していますか?
イルトロン 2007.09.10 04:07

...

int ComparePrice(double a, double b)
{
a -= b;
b = Point / 2;
なら
を返す(1)。
if (a < -b)
を返します(-1)。
を返します(0)。
}
...
念のためですが、私が提案したのはComparePriceという関数です。:)

お気づきのように、ComparePriceという関数も引用しています。ただ、あなたのはすでに VBAGによって 修正されています。だから、原始的なバージョンというのは、オリジナルのもの、つまり、あなたの機能という意味で言ったのです
私自身、両方の機能をテストしました。はい、より速くなったことがわかりました。しかし、比較の信頼性をどのように確認するのでしょうか?2つの変数doubleの比較で非常に迷っています。間隔をとっているので、すべて正しいはずなのですが!しかし、それでも常に正しく動作するとは限らないという疑惑があるのです

ノーマライゼーションについては、すでにお話ししたとおりです。まず、なぜ それを適用するのか、そして、どこで どのように 適用するのかを教えてください。

ここで、重要な問題がありますね。私自身は、「ダブルを 打てばダブルが 出る」ということをずっと考えていました。
正確な答えは見つかっていません。でも、こんな風に想像することができます。

double a = 2.000000000000
double b = 2.000000000001
double c = 1.9999999999

これらの変数はすべて異なり、最後の一桁まで正確にメモリに保存されています。
この場合、符号(数字)は私たち自身が定義します。定義されていないものはすべてゼロで埋め尽くされます。

double a = 2.0 と定義した場合、それが 2.0000001 または 1.999999 としてメモリに格納されているとしたら、NormalizeDouble() は不正確な値を返すため、役に立たないことは明らかです!
このようなエラーは、変数の値を記憶しているときにはほとんど発生しないと思います。それに、2.0という数字が1.999999999として格納されることはないと思います。なぜなら、それぞれの文字(桁や点)は、ビット列の特定のビットと一緒に格納されるからですしたがって、2.0という数値は、2.00000...00として安全に保存されます。

もうひとつは、自分たちで兆候を判断しない場合です。

a = 4.0;
b = 2.0;
c = a / b // - 「除算」演算はプロセッサ、というかコプロセッサが行い、プリメンテを文字(数字)で埋めていく。

操作後、それは可能です。
最も一般的です。
с = 2.000...0
с= 1.99999999...
с= 2.00000001...

つまり、真の値からわずかな差で結果が異なることが多いのです。

大きなエラーはほとんど発生しません。
с = 2.3

ここで、2つの説明があります。
1) aまたはbを呼び出す際に、ビット列の一部がメモリ上で影響を受けた、すなわち変数aおよびbが変更された。
2) "除算 "動作中にエラーが発生した。

2)が一番多く発生すると思います。なぜ、わからないのか。それは、コプロセッサが使い勝手が悪くなるほど高度に最適化されることを意図していることと関係があるように思います。

変数と数値2.000...00を比較する場合、等式は明らかに失敗します。すべてのビットが同じになるわけではありません。

そこで、NormalizeDouble()がお役に立ちます!
NormalizeDouble() は、この小さなエラーを「修正」してくれます!
誤差は非常に小さいことが多いので、小さな精度で丸めれば必ず正しい結果が得られる。

こう考えてみてください。
a = 2.111...11 の数字を2桁目に丸め なさい。
NormalizeDouble() は 2.11 を新しい変数に書き込み、残りのビットを 1 ではなく 0 で埋めます!これは、2.11 を新しい変数に書き込み、残りのビットを 1 ではなく 0 で埋めます。
こんな感じになると思います。

double MyNormalizeDouble(double value, int digits)
{
    int factor = MathRound( MathPow(10, digits) ); // factor - это множитель,
                                                      с помощью которого мы из VALUE сделаем целое число
    double result = MathRound(factor * value) / factor;
    
    return(result);
}
ここでは、なぜNormalizeDouble()が必要なのか、その理由を一生懸命に説明しました。

最近までこの説明に納得していたが、最近になって、この方式が常に有効であるとは限らないことを確信した。

NormalizeDouble(a, 2) !OC!NormalizeDouble(b, 2) ここで !OC!- は比較演算子です。
しかし、私の理解では、それは常に機能するはずです。
ですから、理路整然としたわかりやすい批判があれば、喜んでお受けしますよ
 
gravity001:

また、他のスレッドでは、開発者自身が、ダブル定数も比較しない方が良い!!と書いています。
これはニュースだ!これが実質的な質問と言うものなのか!?
もし可能なら、リンクをお願いします

開発者の方に質問です。

定数を用いた倍精度比較の限界や問題点を教えてください。
1.
double a=1.23456789;
ダブルビー

if(a>b) or if(a<b)

しかもこの形で。
2.
#define a 1.23456789;

ダブルビー

if(a>b) or if(a<b)
 
gravity001:

特に、オリジナル版では定数桁の 代わりに b = Point / 2 を使っていたので、ここで既に正規化されていない2つの変数が2つ?

だから、b =Point / 2 を定数に置き換えたのです(1.演算回数が少ない - 速い 2.定数転送を明示 - 信頼性が高い)

しかし、二重定数比較の信頼性が低いというご指摘に照らすと、本末転倒になりますね。この問題については、もっと詳しく調べる必要があります。

開発者はなんと言うのだろう。
 
VBAG писал (а):
...
今さらですが、これはニュースですそれが実質的な質問と言うものだ!
もし可能なら、リンクをお願いします
...
そうなんです、すぐに貼り付けようと思ってリンクを探していたのですが、見つかりませんでしたどこかで見た記憶があるのですが、そういう話題がとても多かったです。また、他の掲示板のトピックや、この分野の本から読みました。
誰かがどこかで書いていた記憶があるのですが、どこだか思い出せません(((だから、たぶん、私が書いたのは正しくない。"他のスレッドで開発者自身が書いた"!
申し訳ありません。
でも、もしリンクが見つかったら、必ず投稿してください。

C++の本で読んだような気がします。実数の比較の仕方が書かれていて、整数にするのが一番いいと書いてありました
 
gravity001:
VBAG さんが書き込みました(a):
...
これはニュースです!それが実質的な質問と言うものだ!
もし可能なら、リンクをお願いします
...
そうなんです、リンクを探していて、すぐに挿入したかったのですが、見つかりませんでしたどこかで見た記憶があるのですが、そういう話題がとても多かったです。また、他の掲示板のトピックや、この分野の本から読みました。
誰かがどこかで書いていた記憶があるのですが、どこだか思い出せません(((したがって、おそらく、私が書くのは正しくなかったのでしょう。"他のスレッドで開発者自身が書いた"!
申し訳ありません。
でも、もしリンクが見つかったら、必ず投稿してください。

C++の本で読んだような気がします。実数の比較の仕方が書かれていて、整数にするのが一番いいと書いてありました
ご参加、ご協力ありがとうございました。残念ながら、私はプログラミングの学問的なバックグラウンドを持っていません。だから、もっと聴いて暗記しないといけないんです。そして、開発者の方々が回答し、私の質問を明確にしてくれることを望みます。
開発者の方に質問です。

定数を用いてダブりを比較する場合、どのような制限や問題が考えられるのか、明らかにしてください。
1.
double a=1.23456789;
ダブルビー

if(a>b) or if(a<b)

しかもこの形で。
2.
#define a 1.23456789;

ダブルビー

if(a>b) or if(a<b)
 
このような問題 - 1.3333+0.0004 != 1.3337
 

この会話はいつまでも続くようだ。新しいユーザーが適切な経験と知識を得るまでに、通常、何度か正常化にぶつかることがあります。

もしかしたら、MT5では、比較演算における実数の精度を強制的に小数点以下8桁に制限する(つまり、NormalizeDouble()を強制的に digit=8 で実行する)ことに意味があるのかもしれませんね。また、NormalizeDouble()関数が明示的に指定されている場合のみ、その関数で指定されたパラメータに従って正規化を行う。 この場合、問題が生じる頻度はかなり低くなり、つまりユーザーが指定された精度を正確に必要とする場合にのみ生じる。 私の考えでは、このディックは少し、しかしまだ大根より甘いです。

 
VBAG:
こんにちは。
ご存知のように、計算の正しさだけでなく、書いたコードの信頼性も、プログラミングのスタイルやコードの正確さに依存します。
私たちはおもちゃを作らないので、書かれたプログラムの動作信頼性が第一条件です。ほとんどの計算がダブリングで行われ、そのコードでの正しい比較は
の2つの実数をプログラムコードで表現するには、一定のアプローチと精度が必要です。
私は、「正しい」プログラミングのスタイルを考えようとしているので、このような質問をしました。

式の場合

ダブルエー
ダブルビー

if(a==b) or if(a!=b)
{......}{......}

開発者のおすすめはこれ
//+------------------------------------------------------------------+
//| 2つの実数を比較する関数です。
//+------------------------------------------------------------------+
bool CompareDouble(double 数値1, double 数値2)
{
bool Compare = NormalizeDouble(Number1 - Number2, 8) == 0;
return(Compare)です。
}
//+------------------------------------------------------------------+


このコードは正しいですか?

ダブルエー
ダブルビー

if(a>b) if(a<b)
{......}{......}


一般的なケースでは、ほとんどないでしょう。正しい確認方法を教えてください。
一般的には、どのようなスタイルでダブリングに取り組むのが適切でしょうか。
回答してくださった皆様、ありがとうございました。

せっかく作ったのに...。:)

浮動小数点数の比較は、差のモジュラスを小さな閾値と比較することによって行われます。

例えば、(fabs(d1-d2) < 1e-10)を返す。

何をお茶を濁すんだ・・・。NormalizeDouble(...)関数は、見栄えの良いレポートのためだけのものです。