Caratteristiche del linguaggio mql5, sottigliezze e tecniche - pagina 158

 

C'è una matrice, riempita con valori grandi, circa 10e60, e piccoli, come 1e-40. E c'è un codice come questo

      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;
      }
In circa il 27% dei casi k=-15. In altri casi k=-16. Da qui una domanda: c'è un modo per sostituire l'operazione(stringa) Matrix[i][j] con una funzione di conversione più rigorosa? O forse c'è una funzione che taglia alcune cifre decimali? NormalizeDouble non è corretto, troncherà 1.12345678e-40 in 0. Voglio che tronchi dopo il punto decimale. O la conversione in (stringa) ha una vita propria e non può essere espressa tramite funzioni? Grazie.
 
traveller00:

Modulo di differenza.

 
fxsaber:

Il modulo di differenza.

Potresti essere un po' più specifico? Forse con un esempio di codice? Differenza tra cosa e cosa?

Il punto è che tale doppia conversione(double)((string)Matrix[i][j]);; troncherà un numero incontrollabile di caratteri dopo il punto decimale. Vorrei mantenere questo troncamento da un lato = poterlo ripetere, e dall'altro lato questo numero di caratteri è controllato.

 
traveller00:

Potresti essere un po' più specifico? Forse con un esempio di codice? Differenze tra cosa e cosa?

if (MathAbs(Value1 - Value2) < Epsilon)
 

Ah, capisco il tuo punto di vista. No, la domanda è un po' diversa. Il confronto qui è piuttosto solo un esempio per mostrare che non possiamo sostituire la conversione via (double)((string)Matrix[i][j]); con la conversione via DoubleToString. In effetti, il compito in questione non è un confronto. Si tratta piuttosto di un certo azzeramento della precisione attraverso tale doppia conversione. Da un lato voglio essere in grado di ripetere il ritaglio tramite (string), dall'altro voglio essere in grado di controllare la precisione del ritaglio come fa DoubleToString.

E come domanda collaterale, potrebbe essere che queste conversioni siano fatte in modo diverso e vivano le loro vite separate e non collegate?

 
traveller00:

Ah, capisco il tuo punto di vista. No, la domanda è un po' diversa. Il confronto qui è piuttosto solo un esempio per mostrare che non possiamo sostituire la conversione via (double)((string)Matrix[i][j]); con la conversione via DoubleToString. In effetti, il compito in questione non è un confronto. Si tratta piuttosto di un certo azzeramento della precisione attraverso tale doppia conversione. Da un lato voglio essere in grado di ripetere il ritaglio tramite (string), dall'altro voglio essere in grado di controllare la precisione del ritaglio come fa DoubleToString.

E come nota a margine, mi chiedo se queste conversioni sono fatte in modo diverso e vivono le loro vite separate e non collegate.

Non capisco perché NormalizeDouble eDoubleToString non tisoddisfano, hanno tutta la precisione che vuoi, o vuoi una certa precisione, ma non sai qual è?

 

Sono d'accordo che il compito non è del tutto trasparente. Perché sto cercando di mettere insieme una sorta di stampella per i test.

Diciamo che c'è un numero 1,0123456789e-50. Ho bisogno di arrotondare con una certa precisione in modo che:

1. Per impostazione predefinita, funziona come una doppia conversione via(string).

2. la precisione può essere controllata se lo si desidera.

QuindiNormalizeDouble non è adatto, semplicemente annullerà questo numero. E DoubleToString non permette di ripetere il risultato del passo 1.

Il problema nasce dalla domanda successiva. Come ho scritto sopra, c'è una matrice. Si calcola l'inverso di questa matrice. A volte (forse a causa di errori dovuti ai limiti di precisione del doppio), la matrice risulta essere degenerata e l'inverso non può essere calcolato per essa. Ma se riducete un po' la precisione, sarete ancora in grado di calcolare l'inverso. È per questo che volevo fare dei test e ottenere delle statistiche su quanto il risultato sia simile a quello vero. La doppia conversione tramite (stringa) risolve il problema nella maggior parte dei casi. Ma a volte non è sufficiente e mi piacerebbe poter controllare la precisione del taglio. E DoubleToString, anche con una precisione da -16 a 16, non risolve il problema nella maggior parte dei casi.

 

Potete dirmi per favore, pls.

In indicatore l'ordine delle serie, per esempio close[], è impostato da ArraySetAsSeries() una volta o in qualche altro modo?

Viene fatto in OnCalculate() o può essere fatto in OnInit()?

Ho incontrato una situazione confusa:

L'ordine in close[], impostato da AS_SERIES all'entrata sul primo tick, sul prossimo tick cambia spontaneamente in normale, cioè !AS_SERIES.

Non ho trovato nessuna ragione per farlo nel codice.

 
Yurixx:

Potete dirmi per favore, pls.

In indicatore l'ordine delle serie, per esempio close[], è impostato da ArraySetAsSeries() una volta o in qualche altro modo?

Viene fatto in OnCalculate() o in OnInit()?

Ho incontrato una situazione confusa:

L'ordine in close[], impostato da AS_SERIES all'entrata sul primo tick, sul prossimo tick cambia spontaneamente in normale, cioè !AS_SERIES.

Non ho trovato la ragione di questo nel codice.

E non vedrete l'array close[] in OnInit(). E nessuno degli altri parametri predefiniti di OnCalculate().

Quindi conclusione - solo in OnCalculate().

 
Artyom Trishkin:

E in OnInit() non vedrete l'array close[]. E nessuno degli altri parametri predefiniti di OnCalculate().

Quindi conclusione - solo in OnCalculate().

Sono arrivato alla stessa conclusione. )))

Resta da vedere se impostare questo ordine una volta sia sufficiente o se debba essere fatto ad ogni tick.