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

 

I think I am not the only one who had a rare situation where I needed to get the number of decimal places, and Digits() function works only with quotes, and besides there is no information about it anywhere (at least at the time of writing this post I have not found it before, so I want to show what solution I found).


As it turned out, the essence of the banal simple, but still has one drawback - this function does not recognize zeros, if after them there are no other digits. For example, this function will return 2 when followed by 0.01, but when followed by 0.0000 it will return 0 (i.e. it can't see four zeros). So, consider this shortcoming in your developments.


Code in MQL4

int Digits_values(double value)
  {
   int digits = 0;
   string string_value = (string)value;
   int limit = StringLen(string_value);
   for(int i = 1; i < limit; i++)
     {
      if(StringSubstr(string_value,i,1) == ".")
        {
         digits = limit - (i + 1); break;
        };
     };
  //-----------------------------------------------------------------
   return(digits);
  }


The code at MQL5

int Digits_values(double value)
  {
   int digits = 0;
   string string_value = (string)value;
   int limit = StringLen(string_value);
   for(int i = 1; i < limit; i++)
     {
      if(StringSubstr(string_value,i,1) == ".")
        {
         if(i == limit - 2)
           {
            if(StringSubstr(string_value,limit-2,1) == "." && StringSubstr(string_value,limit-1,1) == "0")
              {
               break;
              }
            else
              {
               digits = 1; break;
              };
           }
         else
           {
            digits = limit - (i + 1); break;
           };
        };
     };
  //-----------------------------------------------------------------
   return(digits);
  }

The MQL5 code had to be slightly improved, as apparently in MQL5 variables of double type are automatically assigned 0 at the end, no matter whether the variable is an integer or not. For this reason, the function has never returned 0

 
Alexandr Sokolov:

I think I am not the only one who had a rare situation where I needed to get the number of decimal places, and Digits() function works only with quotes, and besides there is no information about it anywhere (at least at the time of writing this post I found it before, so I want to show what solution I found).

As it turned out the essence is banally simple, but still has one drawback - this function does not recognize zeros, if after them there are no other digits. For example, the function will return 2 when followed by 0.01, but when followed by 0.0000 it will return 0 (which means it can't see four zeros). Therefore, you should consider this shortcoming in your developments.

The code in MQL5 had to be slightly improved, since apparently in MQL5 variables of double type are automatically assigned , 0 at the end, no matter if the variable is assigned to an integer or not. For this reason, the function has never returned 0.

Suppose we give the number 2.4875 and the function returns 4.

What should we do with it? Something I don't get the point of(

 
Alexandr Sokolov:

I think I am not the only one who had a rare situation where I needed to get the number of decimal places, and Digits() function works only with quotes, and besides there is no information about it anywhere (at least at the time of writing this post I found it before, so I want to show what solution I found).


As it turned out the essence is banally simple, but still has one drawback - this function does not recognize zeros, if after them there are no other digits. For example, this function will return 2 when followed by 0.01, but when followed by 0.0000 it will return 0 (which means it can't see four zeros). So, consider this shortcoming in your developments.


Code in MQL4


The code at MQL5

The MQL5 code had to be slightly improved, as apparently in MQL5 variables of double type are automatically assigned 0 at the end, no matter whether the variable is an integer or not. For this reason, the function has never returned 0.

after
string string_value = (string)value;

don't read any further :-)

 
Vitaly Muzichenko:

Suppose we give the number 2.4875, the function will return 4.

What do we do with it? I don't seem to get the point(

Depending on who needs what. For example I needed integers to calculate the correlation index more easily

 
Maxim Kuznetsov:

you don't need to read any further :-)

What's not clear for a programmer here?)

 
If anything, there is a StringFind() function, no need to loop through the characters to find it.
 
Dmitry Fedoseev:
If anything, there is a StringFind() function, no need to loop through the characters to find it.

thanks

 

Pulled out

int GetDigits( double Price )
{
  int Res = 0;

  while ((bool)(Price = ::NormalizeDouble(Price - (int)Price, 8)) && (Res < 8))
  {
    Price *= 10;

    Res++;
  }

  return(Res);
}
 

also a good solution

 
Alexandr Sokolov:

also a good solution

A good solution usually works properly

void OnStart()
{
        double price = 500000000.0001;
        Print( price, ":", GetDigits( price ));
}

Result: 500000000.0001:8

How many digits after the decimal point? Is it really 8 ?

 
A100:

A good solution usually works properly

Result: 500000000.0001:8

How many digits after the decimal point? Is it really eight ?

Yes, eight.

Reason: