Librerías: Math Utils - página 3

 
@fxsaber NormalizeDouble redondea a decimales, que es diferente de redondear a dígitos significativos. SF es 1-15 o 17 inclusive. No hay 0.
 
amrali #:
@fxsaber NormalizeDouble redondea a decimales, que es diferente de redondear a dígitos significativos. SF es 1-15 o 17 inclusive. No hay 0.

No lo he entendido.

 

NormalizarDoble(12.345, 2) -> 12.35

RoundToSignificantDigits(12.345, 2) -> 12


EqualDouble() se utiliza para comparar cantidades sospechosamente iguales como 1.123456 y 1.23456789

también se pueden utilizar números muy grandes como 1234567891234.1234 y 1234567891234.1255

sin conocer los dígitos decimales de los números que se comparan entre sí.
 
Parece que entiendo el término "dígitos significativos de precisión" de forma diferente.
 
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...
 

Foro sobre trading, sistemas automatizados de trading y prueba de estrategias de trading

Bibliotecas: Math Utils

fxsaber, 2023.02.21 21:01

Necesitas aprender a hacer mediciones de rendimiento adecuadas.

#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 veces más rápido.


@fxsaber ¡No lo comprobé después de ti, ayer!

Pero, cuando volví hoy, me encontré con que la evaluación comparativa mal. Usted acaba de evaluación comparativa del operador modulo %, pero con algunas optimizaciones internas del compilador que tiene esa diferencia poco realista.

Usé este simple benchmark para volver a comprobarlo. Ambas funciones son suficientemente rápidas. Así que, ¡no hay cambio!

#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; // usar doble para evitar optimizar la expresión.
   int runs = 1 e8;

   Benchmark(runs, sum1 += EqualDoubles(1.12345, 1.12345));
   Benchmark(runs, sum1 += EqualDoubles_v2(1.12345, 1.12345));
   Print(sum1);
  }
//+------------------------------------------------------------------+
// suma1+=EqualDoubles(1.12345,1.12345) -> 110 milisegundo
// suma1+=EqualDoubles_v2(1.12345,1.12345) -> 125 milisegundo
// 200000000.0
 
amrali #:

¡@fxsaber No he comprobado después de ti, ayer!

Pero, cuando volví hoy, me encontré con que la evaluación comparativa mal. Usted acaba de evaluación comparativa del operador modulo %, pero con algunas optimizaciones internas del compilador que tiene esa diferencia poco realista.

Usé este simple benchmark para volver a comprobarlo. Ambas funciones son suficientemente rápidas. Así que, ¡no hay cambio!

Estás sacando conclusiones erróneas.

   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

significa que las llamadas a la función no fueron optimizadas por el compilador. No sé por qué manipulas el 3er argumento, déjalo como parámetro por defecto y vuelve a probar.

Utiliza un bucle simple.

void OnStart()
  {
   double sum = 0; // usar doble para evitar optimizar la expresión.
   uint t1 = GetTickCount();
   for (int i = 0; i < runs; ++i)
   {
    sum += !EqualDoubles(1.12345, 5.12345);
   }
   Print("EqualDoubles -> ", GetTickCount() - t1, " msec");  // 109 mseg
   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 mseg
   Print(sum);
  }
 
amrali #:

significa que las llamadas a la función no fueron optimizadas por el compilador. No sé por qué manipulas el 3er argumento, déjalo como parámetro por defecto y vuelve a probar.

Utiliza un bucle simple.

Desafortunadamente, no entiendes lo que estás midiendo.

Desactiva las optimizaciones del compilador y prueba de nuevo.


 

Entonces, ¿por qué desactivar? Escribo la función y luego dependo del compilador optimizador.

Si no, programaría en ensamblador como en los viejos tiempos :-)