Características del lenguaje mql5, sutilezas y técnicas - página 158

 

Hay una matriz, llena de valores grandes, alrededor de 10e60, y pequeños, como 1e-40. Y hay un código como este

      for(k=-16;k<=16;++k)
      {
        double Tmp1=(double)(DoubleToString(Matrix[i][j],k));
        double Tmp2=(double)((string)Matrix[i][j]);
        if(Tmp1==Tmp2)
          break;
      }
En un 27% de los casos k=-15. En otros casos k=-16. De ahí una pregunta: ¿hay alguna forma de sustituir la operación(cadena)Matriz[i][j] por una función de conversión más estricta? ¿O tal vez hay una función que corta algunos de los decimales? NormalizeDouble no es correcto, truncará 1.12345678e-40 en 0. Quiero que trunque después del punto decimal. ¿O la conversión a (cadena) tiene vida propia y no puede expresarse mediante funciones? Gracias.
 
traveller00:

Módulo de diferencia.

 
fxsaber:

El módulo de diferencia.

¿Podría ser un poco más específico? ¿Tal vez con un ejemplo de código? ¿Diferencia entre qué y qué?

La cuestión es que esa conversión doble(doble)((cadena)Matriz[i][j]);; truncará un número incontrolable de caracteres después del punto decimal. Me gustaría mantener este truncamiento por un lado = poder repetirlo, y por otro lado se controla este número de caracteres.

 
traveller00:

¿Podría ser un poco más específico? ¿Tal vez con un ejemplo de código? ¿Diferencias entre qué y qué?

if (MathAbs(Value1 - Value2) < Epsilon)
 

Ah, ya veo lo que quieres decir. No, la pregunta es un poco diferente. La comparación aquí es más bien como un ejemplo para mostrar que no podemos reemplazar la conversión a través de (double)((string)Matrix[i][j]); con la conversión a través de DoubleToString. De hecho, la tarea en cuestión no es una comparación. Se trata más bien de un cierto restablecimiento de la precisión a través de esa doble conversión. Por un lado quiero poder repetir el recorte a través de (string), por otro lado quiero poder controlar la precisión del recorte como lo hace DoubleToString.

Y como pregunta al margen, ¿podría ser que estas conversiones se hagan de forma diferente y vivan su vida separada y sin relación?

 
traveller00:

Ah, ya veo lo que quieres decir. No, la pregunta es un poco diferente. La comparación aquí es más bien como un ejemplo para mostrar que no podemos reemplazar la conversión a través de (double)((string)Matrix[i][j]); con la conversión a través de DoubleToString. De hecho, la tarea en cuestión no es una comparación. Se trata más bien de un cierto restablecimiento de la precisión a través de esa doble conversión. Por un lado quiero poder repetir el recorte a través de (cadena), por otro lado quiero poder controlar la precisión del recorte como lo hace DoubleToString.

Y como nota al margen, me pregunto si estas conversiones se hacen de forma diferente y viven su vida separada y sin relación.

No entiendo por qué NormalizeDouble yDoubleToString no tesatisfacen, tienen la precisión que quieras, ¿o quieres alguna precisión, pero no sabes cuál es?

 

Estoy de acuerdo en que la tarea no es del todo transparente. Porque estoy tratando de armar una especie de muleta para las pruebas.

Digamos que hay un número 1,0123456789e-50. Necesito redondearlo con cierta precisión para que:

1. Por defecto, funciona como una conversión doble vía(cadena).

2. La precisión puede controlarse si se desea.

Por lo tanto,NormalizeDouble no es adecuado, simplemente anulará este número. Y DoubleToString no permite repetir el resultado del paso 1.

El problema crece a partir de la siguiente pregunta. Como he escrito más arriba, hay una matriz. Se calcula la inversa de esta matriz. A veces (quizás por errores debidos a las limitaciones de precisión del doble), la matriz resulta ser degenerada y no se puede calcular la inversa. Pero si reduces un poco la precisión, podrás calcular la inversa. Por eso quería hacer algunas pruebas y obtener algunas estadísticas para saber hasta qué punto el resultado es similar al verdadero. La doble conversión mediante (cadena) resuelve el problema en la mayoría de los casos. Pero a veces no es suficiente y me gustaría poder controlar la precisión del corte. Y DoubleToString, incluso con una precisión de -16 a 16, no resuelve el problema en la mayoría de los casos.

 

Me lo puedes decir por favor, por favor.

En el indicador el orden de las series, por ejemplo, close[], se establece mediante ArraySetAsSeries() una vez o de alguna otra manera?

¿Se hace en OnCalculate() o se puede hacer en OnInit()?

Me he encontrado con una situación confusa:

El orden en close[], establecido por AS_SERIES al entrar en el primer tick, en el siguiente tick cambia espontáneamente a normal, es decir, !AS_SERIES.

No he encontrado ninguna razón para hacer esto en el código.

 
Yurixx:

Me lo puedes decir por favor, por favor.

En el indicador el orden de las series, por ejemplo, close[], se establece mediante ArraySetAsSeries() una vez o de alguna otra manera?

¿Se hace en OnCalculate() o en OnInit()?

Me he encontrado con una situación confusa:

El orden en close[], establecido por AS_SERIES al entrar en el primer tick, en el siguiente tick cambia espontáneamente a normal, es decir, !AS_SERIES.

No he encontrado la razón de ello en el código.

Y no verás el array close[] en OnInit(). Y ninguno de los otros parámetros predefinidos de OnCalculate().

De ahí la conclusión: sólo en OnCalculate().

 
Artyom Trishkin:

Y en OnInit() no verás el array close[]. Y ninguno de los otros parámetros predefinidos de OnCalculate().

De ahí la conclusión: sólo en OnCalculate().

Llegué a la misma conclusión. )))

Queda por ver si basta con fijar esta orden una vez o si debe hacerse en cada tic.

Razón de la queja: