ライブラリ: 数学ユーティリティ - ページ 3

 
fxsaber NormalizeDoubleは小数点以下を四捨五入しますが、これは有効桁数を四捨五入するのとは異なります。SFは1〜15または17を含む。0はない。
 
amrali #:
fxsaber NormalizeDoubleは小数点以下を四捨五入しますが、これは有効桁数を四捨五入するのとは異なります。SFは1〜15または17を含む。0はない。

よくわからなかった。

 

NormalizeDouble(12.345, 2) -> 12.35

有効数字への丸め(12.345, 2) -> 12


EqualDouble() は、1.123456 と 1.23456789 のように等しいと思われる金額を比較するために使用します。

また、1234567891234.1234 と1234567891234.1255 の ように非常に大きな数値を比較することもできます。

のような非常に大きな数値の比較にも使用できます。
 
精度の有効桁数」という用語について、私は異なる理解をしているようだ。
 
Wikiwand - Significant figures
  • www.wikiwand.com
Significant figures (also known as the significant digits , precision or resolution ) of a number in positional notation are digits in the number that are reliable and necessary to indicate the quantity of something. If a number expressing the result of a measurement (e.g., length, pressure, volume, or mass) has more digits than the number of...
 

取引、自動取引システム、取引戦略のテストに関するフォーラム

ライブラリ数学ユーティリティ

fxsaber, 2023.02.21 21:01

適切なパフォーマンス測定の方法を学ぶ必要があります。

#include <fxsaber\Benchmark\Benchmark.mqh> //https://www.mql5.com/ru/code/31279

#define  BENCH(A) for (int i = 0; i < 1 e8; i++) Tmp += A

void OnStart ()
{
  int Tmp = 0;  
  _BV(BENCH(EqualDoubles(1.2345, 5.4321, i % 15)), 1) // 3953430 mcs.
  Print(Tmp);
  
  Tmp = 0;
  _BV(BENCH(EqualDoubles2(1.2345, 5.4321, i % 15)), 1) // 182654 mcs.
  Print(Tmp);  
}

21倍速い。


@fxsaber 昨日はあなたの後をチェックしませんでした!

でも、今日戻ってきたら、あなたが間違ったベンチマークをしていたことがわかりました。modulo %演算子をベンチマークしただけなのに、コンパイラの内部最適化で非現実的な差が出てしまったんだ。

この簡単なベンチマークを使って再チェックしてみた。どちらの関数も十分に速い。つまり、変更はない!

#define  Benchmark(runs, expression)                                  \
do {                                                                 \
   uint t0 = GetTickCount();                                         \
   for (int i = 0; i < (runs); ++i) { (expression); }                \
   printf("%s -> %I64d millisec", #expression, GetTickCount() - t0); \
} while(0)
//+------------------------------------------------------------------+
void OnStart()
  {
   double sum1 = 0; // 式の最適化を避けるためにdoubleを使う。
   int runs = 1 e8;

   Benchmark(runs, sum1 += EqualDoubles(1.12345, 1.12345));
   Benchmark(runs, sum1 += EqualDoubles_v2(1.12345, 1.12345));
   Print(sum1);
  }
//+------------------------------------------------------------------+
// sum1+=等倍(1.12345,1.12345) -> 110ミリ秒
// sum1+=EqualDoubles_v2(1.12345,1.12345) -> 125ミリ秒
// 200000000.0
 
amrali #:

昨日はあなたの後をチェックしなかった

でも、今日戻ってみたら、ベンチマークが間違っていました。modulo % 演算子をベンチマークしただけなのに、コンパイラの内部最適化で非現実的な差が出てしまったんだ。

この簡単なベンチマークを使って再チェックしてみた。どちらの関数も十分に速い。つまり、変更はない!

あなたは間違った結論を出している。

   Benchmark(runs, sum1 += EqualDoubles(1.2345, 5.4321, i ? 10 : 15));
   Benchmark(runs, sum1 += EqualDoubles_v2(1.2345, 5.4321, i ? 10 : 15));
sum1+=EqualDoubles(1.2345,5.4321,i?10:15) -> 4140 millisec
sum1+=EqualDoubles_v2(1.2345,5.4321,i?10:15) -> 110 millisec
 
// 200000000.0

関数呼び出しがコンパイラによって最適化されていないことを意味します。なぜ第3引数を操作するのかわかりません。デフォルト・パラメーターにしておいて、再度テストしてください。

単純なループを使ってください。

void OnStart()
  {
   double sum = 0; // 式の最適化を避けるためにdoubleを使う。
   uint t1 = GetTickCount();
   for (int i = 0; i < runs; ++i)
   {
    sum += !EqualDoubles(1.12345, 5.12345);
   }
   Print("EqualDoubles -> ", GetTickCount() - t1, " msec");  // 109ミリ秒
   Print(sum);

   uint t2 = GetTickCount();
   for (int i = 0; i < runs; ++i)
   {
    sum += !EqualDoubles_v2(1.12345, 5.12345);
   }
   Print("EqualDoubles -> ", GetTickCount() - t2, " msec");  // 125ミリ秒
   Print(sum);
  }
 
amrali #:

関数呼び出しがコンパイラによって最適化されていないことを意味します。なぜ第3引数を操作するのか分かりませんが、デフォルト・パラメーターのままにしておいて、再度テストしてください。

単純なループを使ってください。

残念ながら、あなたは何を測定しているのか理解していません。

コンパイラの最適化を無効にして試してみてください。


 

では、なぜ無効にするのか?私は関数を書き、最適化コンパイラに依存する。

そうでなければ、昔のようにアセンブリでプログラムすることになる。)