NormalizeDoubleによるMT4での数値の丸め方 - ページ 14

 

むかしむかし、底辺と上辺を丸くする機能を作りました

誰かの役に立つかもしれない

//+------------------------------------------------------------------+
double RoundMax(double price,double symbol_point,int symbol_digits)
  {
   return(NormalizeDouble(price+MyK(price,symbol_point,symbol_digits)*symbol_point, symbol_digits-1));
  }
//+------------------------------------------------------------------+
double RoundMin(double price,double symbol_point,int symbol_digits)
  {
   return(NormalizeDouble(price-MyK(price,symbol_point,symbol_digits)*symbol_point, symbol_digits-1));
  }
//+------------------------------------------------------------------+
int MyK(double price,double symbol_point,int symbol_digits)
  {
   double tmp1=NormalizeDouble(price, symbol_digits);
   double tmp2=NormalizeDouble(price, symbol_digits-1);
   return((MathAbs(tmp1-tmp2)<symbol_point)?10:5);
  }
//+------------------------------------------------------------------+
 
Victor Nikolaev:

むかしむかし、底辺と上辺を丸めるための機能を作りました

誰かの役に立つかもしれない

ありがとうございます、コレクションとして手に入れます。
 
lilita bogachkova:

0.999999999999の 結果を得るようにする

X = 0.99999999999999999

10*X = 10*0.99999999999999999

10*x-x = 10*0.9999999999-0.99999999

9*X = 9*0.99999999999999999

となり、9*X = 9 または X = 1 (1)となる。

v1 = (1/3) = 0.33333333|v2 = 3*(1/3) = 1.00000000

または0.9999999999=1.0

v1 (1.00000000) >= 1.0

この場合、0.9999999999999は1.0を表します。しかし、タスクは「捨てる」ことなので、結果には9が含まれていなければなりません。
 

皆さん、参考になるスレッドをありがとうございました

NormalizeDoubleで 1桁多く丸め、最後の1桁を切り捨てるという解決策を選択しました。ここまでは完全に適任です。

 

また四捨五入の話か......。

状況に応じてアドバイスをお願いします(トマトを投げないでください、私は人情派です)。

があり、そのような変数があります。

      double delta=NormalizeDouble(new_lot-sum_lots,Lots_Digits);

      if(delta>0) delta-=OrderLots();

      if(delta<0) delta+=OrderLots();

デルタはもともと正規化されています。

OrderLotsは、おそらく正規化されたダブを返すはずです。

が、なぜかまれに2.775557561562891e-17のような数字が表示されることがある。

だから、ほぼゼロだけどゼロじゃない......。

最初の質問:これは正常なのでしょうか?

2つ目の質問ですが、テールを避けるために2回目の正規化を行うだけで十分なのでしょうか?

3つ目の質問です(どうせ理解できないだろうという気もしますが、とりあえず質問します)。

正規化された2つの数を足すと非正規化された数になることがありますか?

P.S.もう一度この話を持ち出すのは申し訳ないのですが、私にはもう一度すべてを読み返すだけの力がないのです。


 
transcendreamer:

また四捨五入の話か......。

状況に応じてアドバイスをお願いします(トマトを投げないでください、私は人情派です)。

があり、そのような変数があります。

      double delta=NormalizeDouble(new_lot-sum_lots,Lots_Digits);

      if(delta>0) delta-=OrderLots();

      if(delta<0) delta+=OrderLots();

デルタはもともと正規化されています。

OrderLotsは、おそらく正規化されたダブを返すはずです。

が、なぜかまれに2.775557561562891e-17のような数字が表示されることがある。

だから、ほぼゼロだけどゼロじゃない......。

最初の質問:これは正常なのでしょうか?

2つ目の質問ですが、テールを避けるために2回目の正規化を行うだけで十分なのでしょうか?

3つ目の質問です(どうせ理解できないだろうという気もしますが、とりあえず質問します)。

正規化された2つの数を足すと非正規化された数になることがありますか?

P.S.再びこの話題で恐縮ですが、すべてを読み返す気力はありません。

  1. はい。
  2. はい。
  3. はい。
 
fxsaber:
  1. はい。
  2. はい。
  3. はい。
ありがとうございました。
 
transcendreamer:

追伸:またこの話題で申し訳ないのですが、もう一度やり直す気力がありません。

自分でいろいろな例を使って確認したほうが、理解が深まりますよ。

ただ、やり方が間違っているんです。

if(delta>0)

が、このように

if(delta>0.0)

ダブルナンバーの場合。本当に重要かどうかはわかりませんが、私のバリアントでエラーになったことはありません(同じタイプの変数のみを比較するようにしています)。

 
Andrey Dik:

本当に重要か どうかはわかりませんが、私のバージョンでエラーに遭遇したことはありません(同じ種類の変数のみを比較するようにしています)。

そんなことはない。
 
10進法では1/3など、無限小数でしか表現できない数字もある。しかし、1/3は3次系では無限小数ではなく、そこでは==0.1である。つまり、異なる数体系には、それぞれの無限分率が存在するのです。その結果、10進数で無限大でない分数は、2進数では1にもなる。例:0.1, 0.2, 0.3, 0.4, ・・・。は、正確な2値表現がありません。NormalizeDoubleを 10回呼ぶと、0.1999999999・・・1か0.200000・・・1になります。 よくわからないけど、これはニュースかも。