Ottenere il numero di posizioni decimali di qualsiasi numero (non solo le virgolette) bypassando Digits() in MQL4 e MQL5 - pagina 7

 

basato su un articolo sui mozzi:https://habr.com/company/xakep/blog/257897/

#property copyright "IgorM"
#property link      "https://www.mql5.com/ru/users/igorm"
#property version   "1.00"
//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart()
  {
   double a=1.123456;
   Print(DoubleToDigits(a));
  }
//+------------------------------------------------------------------+
int DoubleToDigits(double value)
  {
   const double digits[18]={1 e17,1 e16,1 e15,1 e14,1 e13,1 e12,1 e11,1 e10,1 e9,1 e8,1 e7,1 e6,1 e5,1 e4,1 e3,1 e2,1 e1,1.0};
   double absvalue=fabs(value);
   int i,decimal=(int)absvalue;
   double real=floor((absvalue-decimal)*1 e18+0.5)-0.5;
   double normalize=fmod(real,1 e3);
   if(normalize>0.0)
     {
      if(normalize>51.5) real+=1 e3-normalize; else real-=normalize;
     }
   double res,last=0.0;
   for(i=0;i<18;i++)
     {
      res=real-fmod(real,digits[i]);
      if(last-res>=0.0) break; else last=res;
     }
   return(i);
  }
//+------------------------------------------------------------------+

non proprio testato, ma sembra funzionare

Всё, точка, приплыли! Учимся работать с числами с плавающей точкой и разрабатываем альтернативу с фиксированной точностью десятичной дроби
Всё, точка, приплыли! Учимся работать с числами с плавающей точкой и разрабатываем альтернативу с фиксированной точностью десятичной дроби
  • habr.com
Сегодня мы поговорим о вещественных числах. Точнее, о представлении их процессором при вычислении дробных величин. Каждый из нас сталкивался с выводом в строку чисел вида 3,4999990123 вместо 3,5 или, того хуже, огромной разницей после вычислений между результатом теоретическим и тем, что получилось в результате выполнения программного кода...
 
Igor Makanu:

basato su un articolo sui mozzi:https://habr.com/company/xakep/blog/257897/

non proprio testato, ma sembra funzionare

Se dà il risultato corretto di 0,07 allora funziona correttamente.

 
Alexey Viktorov:

Se dà il risultato corretto di 0,07 allora funziona correttamente.

non funziona ((((

 
Igor Makanu:

non funziona ((((

E nessun algoritmo funzionerà...

 
Alexey Viktorov:

E nessun algoritmo funzionerà...

sarà, ma il problema è nella precisione data e nella convenienza di grandi costi di calcolo, il numero di doppia precisione può essere ricalcolato in qualsiasi formato:±sign - (1+mantissa/252) × 2 ordine- 1023

È facile estrarre la mantissa e l'ordine, ma non è interessante risolvere questo problema direttamente.

 
Igor Makanu:

sarà, ma il problema è nella precisione data e nella convenienza di grandi costi di calcolo, il numero di doppia precisione può essere ricalcolato in qualsiasi formato:±sign - (1+mantissa/252) × 2 ordine- 1023

È facile isolare la mantissa e l'ordine, ma non è interessante risolvere questo problema di petto

Se la precisione è data, allora tutta questa storia non ha senso. Ho già fatto un esempio, 0,07 ha due cifre decimali. Ma se provate a calcolare il numero di cifre programmaticamente, otterrete tredici... E 0,07 non è il risultato di calcoli, ma è inserito manualmente, nemmeno attraverso una variabile.

 

C'è anche questa opzione:

#define  EPSILON   0.000000001
#define  MORE(A,B) ((A)-(B)>EPSILON)

int Digits(double value)
  {
   int digits=0;
   while(MORE(1.0/MathPow(10,digits),value)) 
      digits++;
   return(digits);
  }
 
Mesaoria:

Torna in te. Questa è una sciocchezza che non dovrebbe nemmeno essere discussa seriamente.

L'autore ha semplicemente una totale incomprensione del funzionamento interno delle doppie variabili.

О!

 
Alexandr Sokolov:
Non ho preteso di sapere tutto, meglio dirmi cosa c'è di sbagliato o mostrarmi la tua versione

Volete sapere quanti decimali sono definiti in ogni variabile di tipo double nel vostro programma. Questa è l'assurdità. Tutte le variabili di tipo double hanno la stessa rappresentazione. Sono rappresentati come Float - in virgola mobile. A volte il punto è a sinistra, a volte a destra - dipende dal valore del numero. Un milione e un milionesimo sono rappresentati con una precisione diversa.

 
Konstantin Gruzdev:

Esiste anche una tale variante:

No, non funzionerà, l'ho fatto ieri tramite conversione di tipo, ecco lo script, il tuo esempio e il mio:

#define  EPSILON   0.000000001
#define  MORE(A,B) ((A)-(B)>EPSILON)

int Digit(double value)
  {
   int digits=0;
   while(MORE(1.0/MathPow(10,digits),value)) 
      digits++;
   return(digits);
  }
//+------------------------------------------------------------------+
int DoubleToDigits(double value)
 {
   double absvalue=NormalizeDouble(fabs(value-int(value)),15);
   int res=StringLen(string(absvalue))-2;
   return(res<=0?0:res);
 }
//+------------------------------------------------------------------+
void OnStart()
  {
   double f = 122334550.007;
   Print("1. DoubleToDigits() = ",DoubleToDigits(f));
   Print("1. Digit() = ",Digit(f));
   f = 0.007;
   Print("2. DoubleToDigits() = ",DoubleToDigits(f));
   Print("2. Digit() = ",Digit(f));
  }

risultati:

2018.11.13 01:49:16.131 tst (EURUSD,M30) 1. DoubleToDigits() = 11

2018.11.13 01:49:16.131 tst (EURUSD,M30) 1. Cifra() = 0

2018.11.13 01:49:16.131 tst (EURUSD,M30) 2. DoubleToDigits() = 3

2018.11.13 01:49:16.131 tst (EURUSD,M30) 2. Cifra() = 3



potete cercare su GoogleFP-Printing-PLDI96.pdf, ma dubito che qualcuno farà tutto secondo l'algoritmo

Motivazione: