Get the number of decimal places of any numbers (not just quotes) bypassing Digits() in MQL4 and MQL5 - page 7

 

based on an article on the 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);
  }
//+------------------------------------------------------------------+

not really tested, but it seems to work

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

based on an article on the hubs:https://habr.com/company/xakep/blog/257897/

not really tested, but it seems to work

If it gives a correct result of 0.07 then it works correctly.

 
Alexey Viktorov:

If it gives the correct result of 0.07 then it works correctly.

does not work ((((

 
Igor Makanu:

does not work ((((

And no algorithm will work...

 
Alexey Viktorov:

And no algorithm will work...

will be, but the problem is in the given accuracy and in the expediency of large computational costs, the number of double precision can be recalculated in any format:±sign - (1+mantissa/252) × 2 order- 1023

It's easy to extract the mantissa and the order, but it's not interesting to solve this problem directly.

 
Igor Makanu:

will be, but the problem is in the given accuracy and in the expediency of large computational costs, the number of double precision can be recalculated in any format:±sign - (1+mantissa/252) × 2 order- 1023

It is easy to isolate the mantissa and the order, but it is not interesting to solve this problem head-on

If the accuracy is given, then this whole thing makes no sense. I already gave an example, 0.07 has two decimal places. But if you try to calculate the number of digits programmatically, you'll get thirteen... And 0.07 is not the result of calculations, but is entered manually, not even through a variable.

 

There is also this 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:

Come to your senses. This is nonsense that should not even be discussed seriously.

The author simply has a total misunderstanding of the inner workings of double variables.

О!

 
Alexandr Sokolov:
I didn't claim to know everything, better tell me what's wrong or show me your version

You want to know how many decimal places each variable of type double is defined in your program. This is the nonsense. All variables of type double have the same representation. They are represented as Float - floating point. Sometimes the point is to the left, sometimes to the right - it depends on the value of the number. One million and one millionth are represented with different precision.

 
Konstantin Gruzdev:

There is also such a variant:

No, it won't work, I did it yesterday via type conversion, here's the script, your example and mine:

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

results:

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



you can googleFP-Printing-PLDI96.pdf, but I doubt that someone will do everything according to the algorithm

Reason: