Obtener el número de decimales de cualquier número (no sólo las comillas) evitando Digits() en MQL4 y MQL5 - página 22

 
Andrey Khatimlianskii:

No es necesario.

Tienes una boca muy grande, ¿no?

Aquí tenemos un array de 10000 elementos, completamente aleatorio, aleatorizado antes de cada ciclo de ordenación. Tiempo total (ms) para 1000 repeticiones de cada método.

ArraySort incorporado, mi método escrito hace un par de días (antes no me ocupaba de los algoritmos de ordenación en absoluto), y 6 mejores métodos de su biblioteca (el resto eran mucho peores), mientras que eliminé todo lo relacionado con los gráficos de allí...

#include <Sort\GSort.mqh>
#define    ttt                 template<typename T>
#define    test(M,S,EX)        {uint mss=GetTickCount();int nn=(int)pow(10,M);for(int tst=0;tst<nn&&!_StopFlag;tst++){EX;} \
                                printf("%s: loops=%i ms=%u",S,nn,GetTickCount()-mss);}


ttt void a_rand(T&ar[]){for(int i=0;i<ArraySize(ar);i++)ar[i]=T(rand()*rand());}

ttt int TreePop(T&t[],T&ar[],int i=0,int b=0)
 {
  if(t[b+1]>=0)i=TreePop(t,ar,i,(int)t[b+1]);
  ar[i++]=t[b];
  if(t[b+2]>=0)i=TreePop(t,ar,i,(int)t[b+2]);
  return i;
 }

ttt void TreeSort(T&ar[])
 {
  int sz=ArrayRange(ar,0);
  T t[];ArrayResize(t,sz*3);ArrayInitialize(t,-1);
  for(int i=0;i<ArraySize(ar);i++){t[i*3]=ar[i];
    if(!i)continue;
    int b=0;
    while(1)
      if(ar[i]<=t[b])
        if(t[b+1]>=0)b=(int)t[b+1];
        else{t[b+1]=i*3;break;}
      else
        if(t[b+2]>=0)b=(int)t[b+2];
        else{t[b+2]=i*3;break;}}
  TreePop(t,ar);
 }


void OnStart(){
  double ar[];
  int N=10000,k=3;
  ArrayResize(ar,N);

  test(k,"ArraySort(MQL5)",a_rand(ar);ArraySort(ar))
  test(k,"TreeSort(AntFX)",a_rand(ar);TreeSort(ar))
  test(k,"Merge(GSort)",a_rand(ar);GMergesort(ar,0,N-1))
  test(k,"QTernaryLL(GSort)",a_rand(ar);GQSortTernaryLL(ar,0,N-1))
  test(k,"QSortLL(GSort)",a_rand(ar);GQSortTernaryLL(ar,0,N-1))
  test(k,"QSort(GSort)",a_rand(ar);GQSortTernaryLR(ar,0,N-1))
  test(k,"QTernaryLR(GSort)",a_rand(ar);GQSortTernaryLR(ar,0,N-1))
  test(k,"Comb(GSort)",a_rand(ar);GComb(ar))
}
 
Ilya Malev:

Tienes una gran boca, ¿no?

Aquí tenemos un array de 10000 elementos, completamente aleatorio, aleatorizado antes de cada ciclo de ordenación. Tiempo total (ms) para 1000 repeticiones de cada método.

Built-in ArraySort, mi método escrito hace un par de días (antes no hacía algoritmos de ordenación en absoluto), y 6 mejores métodos de su biblioteca (el resto eran mucho peores), mientras que eliminé todo lo relacionado con los gráficos de allí...

A juzgar por el vídeo del artículo, los más rápidos son Count, LSD y MSD.

 
Andrey Khatimlianskii:

A juzgar por el vídeo del artículo, los más rápidos son Count, LSD y MSD.

Nunca esperé a que se completaran estos pases.

 
Alexandr Sokolov:

Creo que no soy el único que ha tenido una situación rara en la que necesitaba obtener el número de decimales, y la función Digits() sólo funciona con comillas, y además no hay información al respecto en ningún sitio (al menos en el momento de escribir este post no la he encontrado antes, así que quiero mostrar la solución que he encontrado).


Al final resultó que, la esencia de la simple banal, pero todavía tiene un inconveniente - esta función no reconoce los ceros, si después de ellos no hay otros dígitos. Por ejemplo, esta función devolverá 2 cuando vaya seguida de 0,01, pero cuando vaya seguida de 0,0000 devolverá 0 (lo que significa que no puede ver cuatro ceros). Por lo tanto, considere esta carencia en sus desarrollos.


Código en MQL4


El código en MQL5

El código de MQL5 tuvo que ser ligeramente mejorado, ya que aparentemente en MQL5 a las variables de tipo doble se les asigna automáticamente 0 al final, sin importar si la variable es un entero o no. Y por esta razón, la función nunca ha devuelto 0.

Si este tema es relevante, aquí está mi ejemplo:

int kol_Z(double zzz) { // calcula el número de decimales

cadena a, d;
int b, c;
a=StringFormat("%g", zzz);
b=StringFind(a,".",0);
c=StringLen(a);
si (b==-1) return(0);
d=Substr(a,b+1);
return(StringLen(d));
}
 
NomadSoul:

si el tema es relevante, aquí está mi opinión al respecto:

Ejemplo:

void OnStart()
{
    Print(kol_Z(1.001234));
}

Resultado: 5 y debería ser 6

 
A100:

Ejemplo:

Resultado: 5, que debería ser 6.

el número de decimales?". ¿Cómo se puede, cuando se le da a un ordenador un número que debe truncar hasta la longitud de la mantisa que tiene, preguntarle dónde estaba el final de esa fracción periódica infinita?

0,00011001100110011(0011) es un número decimal 0,1 en representación binaria. La parte periódica de la fracción infinita está entre paréntesis. Entonces, ¿qué debería responder el ordenador, si sólo almacena las primeras 52 cifras significativas del número infinito en el doble?

A nadie le sorprende que el cortísimo número ternario 0,1 en representación decimal (0,33333...) tenga un número infinito de cifras significativas después de la coma. El binario 0,1 es igual al decimal 0,5 con un número finito de dígitos por feliz accidente, encontrado y reducido un divisor común en las dos bases de los sistemas de notación 2 y 10, es el 2. Los grados de la mitad en ambas representaciones también son buenos: 0,5 => 0,1; 0,05 => 0,01 ; 0,025 => 0,001 ; 0,0125 => 0,0001. Pero en cuanto aparece el 5 en el denominador de una fracción, ya está, hay un montón de cifras significativas.

El número de cifras significativas en la parte fraccionaria está relacionado con el número de dígitos utilizados en la representación, no sólo con el valor del número.

Самый простой способ посчитать количество знаков после запятой?
Самый простой способ посчитать количество знаков после запятой?
  • 2021.01.18
  • www.mql5.com
Есть переменная. Например: double а=0.02; Нужно написать функцию, которая считала бы количество знаков после запятой...
 

1

Lo he hecho tres veces. Está respirando en la nuca del líder... Si alguien lo necesita, la función aquí eshttps://www.mql5.com/ru/code/904, el nombre de la función es SortHoareUp.

 
Dmitry Fedoseev:

Lo he hecho tres veces. Está respirando en la nuca del líder... Si alguien necesita, la función aquí eshttps://www.mql5.com/ru/code/904, el nombre de la función es SortHoareUp.

También existeMathQuickSort() de la biblioteca (#include <Math\Stat\Math.mqh>). Recuerdo que había un artículo en el que escribían que es una biblioteca muy-muy rápida).

No he medido la velocidad, lo uso principalmente porque me permite guardar array de índices de array de origen.

 
Vladimir:

el número de decimales?". ¿Cómo puedes, cuando le das a un ordenador un número que tiene que truncar a la longitud de la mantisa que tiene, preguntarle dónde estaba el final de esa fracción periódica infinita?

0,00011001100110011(0011) es un número decimal 0,1 en representación binaria. La parte periódica de la fracción infinita está entre paréntesis. Entonces, ¿qué debería responder el ordenador, si sólo almacena las primeras 52 cifras significativas del número infinito en el doble?

A nadie le sorprende que el cortísimo número ternario 0,1 en representación decimal (0,33333...) tenga un número infinito de cifras significativas después de la coma. El binario 0,1 es igual al decimal 0,5 con un número finito de dígitos por feliz accidente, encontrado y reducido un divisor común en las dos bases de los sistemas de notación 2 y 10, es el 2. Los grados de la mitad en ambas representaciones también son buenos: 0,5 => 0,1; 0,05 => 0,01 ; 0,025 => 0,001 ; 0,0125 => 0,0001. Pero en cuanto aparece el 5 en el denominador, ya está, hay un montón de cifras significativas.

El número de cifras significativas en la parte fraccionaria está relacionado con el número de dígitos utilizados en la representación, y no sólo con el valor del número.

Sería conveniente definir primero las condiciones del problema a resolver. Si estamos hablando de algún tipo de estudio teórico sobre la representación de los números en el ordenador, tenemos que aclarar más el propósito de este estudio.

Si la pregunta es sobre qué número entero suministrar como segundo argumento a la función NormalizeDouble(), debe utilizar la misma función para encontrar la respuesta. Será el mínimo número entero entre 0 y 8, para el cual el número normalizado será igual al número fuente. Si no se encuentra tal número entero, el número de origen es incorrecto. Este es un ejemplo decódigo en el que se cuenta el número de dígitos para el paso de volumen mínimo.