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

 

basado en un artículo de los 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);
  }
//+------------------------------------------------------------------+

no se ha probado, pero parece que funciona

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

basado en un artículo de los hubs:https://habr.com/company/xakep/blog/257897/

no se ha probado, pero parece que funciona

Si da un resultado correcto de 0,07 entonces funciona correctamente.

 
Alexey Viktorov:

Si da el resultado correcto de 0,07 entonces funciona correctamente.

no funciona ((((

 
Igor Makanu:

no funciona ((((

Y ningún algoritmo funcionará...

 
Alexey Viktorov:

Y ningún algoritmo funcionará...

será, pero el problema está en la precisión dada y en la conveniencia de los grandes costes computacionales, el número de doble precisión puede ser recalculado en cualquier formato:±signo - (1+mantisa/252) × 2 orden- 1023

Es fácil extraer la mantisa y el orden, pero no es interesante resolver este problema directamente.

 
Igor Makanu:

será, pero el problema está en la precisión dada y en la conveniencia de los grandes costes computacionales, el número de doble precisión puede ser recalculado en cualquier formato:±signo - (1+mantisa/252) × 2 orden- 1023

Es fácil aislar la mantisa y el orden, pero no es interesante resolver este problema de frente

Si se da la precisión, entonces todo esto no tiene sentido. Ya di un ejemplo, 0,07 tiene dos decimales. Pero si intentas calcular el número de dígitos mediante programación, obtendrás trece... Y 0,07 no es el resultado de los cálculos, sino que se introduce manualmente, ni siquiera a través de una variable.

 

También existe esta opción:

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

Vuelve a tus cabales. Esto es una tontería que ni siquiera debería discutirse seriamente.

El autor simplemente tiene una total incomprensión del funcionamiento interno de las variables dobles.

¡О!

 
Alexandr Sokolov:
No he pretendido saberlo todo, mejor dime qué es lo que falla o enséñame tu versión

Quieres saber cuántos decimales tiene definida cada variable de tipo double en tu programa. Esto es un disparate. Todas las variables de tipo double tienen la misma representación. Se representan como Float - punto flotante. A veces el punto está a la izquierda, a veces a la derecha - depende del valor del número. Un millón y una millonésima se representan con diferente precisión.

 
Konstantin Gruzdev:

También existe esta variante:

No, no funcionará, lo hice ayer mediante conversión de tipo, aquí está el script, tu ejemplo y el mío:

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

resultados:

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

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



puedes buscar en googleFP-Printing-PLDI96.pdf, pero dudo que alguien haga todo según el algoritmo

Razón de la queja: