Obtenir le nombre de décimales de n'importe quel nombre (pas seulement les guillemets) en contournant Digits() dans MQL4 et MQL5 - page 7

 

d'après un article sur les hubs: 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);
  }
//+------------------------------------------------------------------+

pas vraiment testé, mais cela semble fonctionner

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

d'après un article sur les hubs: https://habr.com/company/xakep/blog/257897/

pas vraiment testé, mais cela semble fonctionner

S'il donne le résultat correct de 0,07, alors il fonctionne correctement.

 
Alexey Viktorov:

S'il donne le résultat correct de 0,07, alors il fonctionne correctement.

ne fonctionne pas ((((

 
Igor Makanu:

ne fonctionne pas ((((

Et aucun algorithme ne fonctionnera...

 
Alexey Viktorov:

Et aucun algorithme ne fonctionnera...

sera, mais le problème est dans la précision donnée et dans l'opportunité de grands coûts de calcul, le nombre de double précision peut être recalculé dans n'importe quel format :±sign - (1+mantisse/252) × 2 ordre- 1023

Il est facile d'extraire la mantisse et l'ordre, mais il n'est pas intéressant de résoudre ce problème directement.

 
Igor Makanu:

sera, mais le problème est dans la précision donnée et dans l'opportunité de grands coûts de calcul, le nombre de double précision peut être recalculé dans n'importe quel format :±sign - (1+mantisse/252) × 2 ordre- 1023

Il est facile d'isoler la mantisse et l'ordre, mais il n'est pas intéressant de résoudre ce problème de manière frontale

Si l'exactitude est donnée, alors toute cette histoire n'a aucun sens. J'ai déjà donné un exemple, 0,07 a deux décimales. Mais si vous essayez de calculer le nombre de chiffres de façon programmatique, vous obtiendrez treize... Et 0,07 n'est pas le résultat de calculs, mais est entré manuellement, même pas par le biais d'une variable.

 

Il y a aussi cette option :

#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:

Reprenez vos esprits. C'est un non-sens qui ne devrait même pas être discuté sérieusement.

L'auteur a tout simplement une incompréhension totale du fonctionnement interne des doubles variables.

О !

 
Alexandr Sokolov:
Je n'ai pas prétendu tout savoir, dis-moi ce qui ne va pas ou montre-moi ta version.

Vous souhaitez connaître le nombre de décimales de chaque variable de type double définie dans votre programme. C'est une absurdité. Toutes les variables de type double ont la même représentation. Ils sont représentés par Float - virgule flottante. Parfois le point est à gauche, parfois à droite - cela dépend de la valeur du nombre. Un million et un millionième sont représentés avec une précision différente.

 
Konstantin Gruzdev:

Il existe également une telle variante :

Non, ça ne marchera pas, je l'ai fait hier par conversion de type, voici le script, votre exemple et le mien :

#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));
  }

les résultats :

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

2018.11.13 01:49:16.131 tst (EURUSD,M30) 1. Digit() = 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. Digit() = 3



vous pouvez googlerFP-Printing-PLDI96.pdf, mais je doute que quelqu'un fasse tout selon l'algorithme