Download MetaTrader 5

NumbersSeparator() function for Print big numbers

To add comments, please log in or register
Lime
642
Lime  

Hi Coders!

I'm looking for a little number to string function.

I have a number, for example: 344256454.23 and I would like to print it in this form: 344,256,454.23

Is it possible with bult-in function? Or I have to write this function?

Thank you.

Relative

whroeder1
14771
whroeder1  
Compiled, not tested
string DoubleToStrCommaSep(double v, int decimals=4){   // 34,256,454.23
    if (decimals == 0)  return( IntToStrCommaSep(v) );
    if (v < 0)          return( "-" + DoubleToStrCommaSep(-v, decimals) );
    int     integer     = v;
    string  fraction    = StringSubstr(DoubleToStr(v - integer, decimals), 1);
    return( IntToStrCommaSep(integer) + fraction);
}
string IntToStrCommaSep(int integer){
    if (integer < 0)    return( "-" + IntToStrCommaSep(-integer) );
    if (integer < 1000) return(integer);
    string left = IntToStrCommaSep(integer / 1000);
    return( left + "," + RJust(integer % 1000, 3) );
}
string  RJust(string s, int size, string fill="0"){
    while( StringLen(s) < size )    s = fill + s;       return(s);             }
Alexander
2441
Alexander  
string FormatNumber(string numb, string delim=",",string dec=".")
{
int pos=StringFind(numb,dec);
if(pos==-1)
   {
   string nnumb=numb;
   string enumb="";
   }
else
   {
   nnumb=StringSubstr(numb,0,pos);
   enumb=StringSubstr(numb,pos);
   }
int cnt=StringLen(nnumb);
if (cnt<4)return(numb);
int x=MathFloor(cnt/3);
int y=cnt-x*3;
string forma="";
if(y!=0)forma=StringConcatenate(StringSubstr(nnumb,0,y),delim);
for(int i=0;i<x;i++)
   {
   if(i!=x-1)forma=StringConcatenate(forma,StringSubstr(nnumb,y+i*3,3),delim);
   else forma=StringConcatenate(forma,StringSubstr(nnumb,y+i*3,3));
   }
forma=StringConcatenate(forma,enumb); 
return(forma);
}   

Example

int start()
{
Comment(FormatNumber("12345678646372821910.45"));
}
Lime
642
Lime  
Thank you very much WHRoeder and Roger!
peter3
11
peter3  

Roger:
string FormatNumber(string numb, string delim=",",string dec="."){ ... }

Roger, thanks for your code above. It worked perfectly. For some strange reason my text objects that included very large numbers formatted by WHRoeder's code printed blanks but on smaller numbers it worked perfectly also. However, since I want to display very large numbers and text objects along with text I'm running out of space because the number of characters in text objects is limited so my large numbers get cut off.

How can I format the number even more so that millions print as M, billions as B and trillions as T with options to choose which ones I want to format? For example, I may choose to only format billions and trillions but leave the millions unformatted as 1,000,000 OR I may choose to format all three, M, B and T.

I looked at both Roger's and WHRoeder's code but could not figure out how to modify them. I'll really appreciate it if Roger or WHRoeder or anyone else can help with this. I did many google searches but couldn't find the answer to this, neither does Hanover's Handy MQL4 Utility have this feature.

For example:

string FormatNumber(6320000000) should print as 6.32B
Thank you very much coders.
whroeder1
14771
whroeder1  
string   DoubleToStrCommaSep(double v, int decimals=4, string s=""){ // 6,454.23
   if(decimals == 0) return( IntToStrCommaSep(v,s) );
   int      integer  = v;
   string   fraction = StringSubstr(DoubleToStr(v - integer, decimals), 1);
   return(IntToStrCommaSep(integer,s) + fraction);
}
string   IntToStrCommaSep(int integer, string s=""){
   if(integer < 0){  s="-";   integer = -integer;  }
   for(string right = ""; integer >= 1000; integer /= 1000)
      right = "," + RJust(integer % 1000, 3, "0") + right;
   return(s + integer + right);
}
Must have tested previous because I changed it.
peter3
11
peter3  
WHRoeder:
Must have tested previous because I changed it.


Thanks WHRoeder. However, just after I asked the question I modified your original code and got it to work.

Here is the modified code that works only up to Billions. If you remove the comment // to compile the code for the larger numbers: Septillion: Y; sextillion: Z; Quintillion: E; Quadrillion: and Q; Trillion, and the function tries to return a number larger than billions then the results are crazy but I con't figure out why so I just commented out those larger numbers. I couldn't find anything wrong with my code so maybe the MQL4 language has a limitation.

//---------------------------------------------------------------------------------
// function: DoubleToStrCommaSep()
// Description: Formats numbers with abbreviations & commas to separate thousands
//---------------------------------------------------------------------------------
// Example: DoubleToStrCommaSep(2560000.56,1) returns 2.6M

string DoubleToStrCommaSep(double v, int decimals=4){ // 34,256,454.23
if (v < 0) return( "-" + DoubleToStrCommaSep(-v, decimals) );

string abbr=""
//Septillion: Y; sextillion: Z; Quintillion: E; Quadrillion: Q; Trillion: T; Billion: B; Million: M;
//if (v > 999999999999999999999999) { v = v/1000000000000000000000000; abbr = "Y"; } else
//if (v > 999999999999999999999) { v = v/1000000000000000000000; abbr = "Z"; } else
//if (v > 999999999999999999) { v = v/1000000000000000000; abbr = "E"; } else
//if (v > 999999999999999) { v = v/1000000000000000; abbr = "Q";} else
//if (v > 999999999999) { v = v/1000000000000; abbr = "T";} else
if (v > 999999999) { v = v/1000000000; abbr = "B";} else
if (v > 999999) { v = v/1000000; abbr = "M";}

v = NormalizeDouble(v,decimals);
int integer = v;

if (decimals == 0) {
return( IntToStrCommaSep(integer) + abbr);
}
else {
string fraction = StringSubstr(DoubleToStr(v - integer, decimals), 1);
return( IntToStrCommaSep(integer) + fraction + abbr);
}
}
string IntToStrCommaSep(int integer){
if (integer < 0) return( "-" + IntToStrCommaSep(-integer) );
if (integer < 1000) return(integer);
string left = IntToStrCommaSep(integer / 1000);
return( left + "," + RJust(integer % 1000, 3));
}
string RJust(string s, int size, string fill="0"){
while( StringLen(s) < size ) s = fill + s; return(s);
}
peter3
11
peter3  

Below is my modification of your changed version but this version also only works up to Billions so the same thing applies:

"If you remove the comment // to compile the code for the larger numbers: Septillion: Y; sextillion: Z; Quintillion: E; Quadrillion: and Q; Trillion, and the function tries to return a number larger than billions then the results are crazy but I con't figure out why so I just commented out those larger numbers. I couldn't find anything wrong with my code so maybe the MQL4 language has a limitation."


//---------------------------------------------------------------------------------
// function: DoubleToStrCommaSep()
// Description: Formats numbers with abbreviations & commas to separate thousands
//---------------------------------------------------------------------------------
// Example: DoubleToStrCommaSep(2560000.56,1) returns 2.6M

string DoubleToStrCommaSep(double v, int decimals=4, string s="") { // 6,454.23

string abbr ="";
//Septillion: Y; sextillion: Z; Quintillion: E; Quadrillion: Q; Trillion: T; Billion: B; Million: M;
//if (v > 999999999999999999999999) { v = v/1000000000000000000000000; abbr = "Y"; } else
//if (v > 999999999999999999999) { v = v/1000000000000000000000; abbr = "Z"; } else
//if (v > 999999999999999999) { v = v/1000000000000000000; abbr = "E"; } else
//if (v > 999999999999999) { v = v/1000000000000000; abbr = "Q";} else
//if (v > 999999999999) { v = v/1000000000000; abbr = "T";} else
if (v > 999999999) { v = v/1000000000; abbr = "B";} else
if (v > 999999) { v = v/1000000; abbr = "M";}

v = NormalizeDouble(v,decimals);
int integer = v;

if (decimals == 0) {
return( IntToStrCommaSep(v,s) + abbr);
}
else {
string fraction = StringSubstr(DoubleToStr(v - integer, decimals), 1);
return(IntToStrCommaSep(integer,s) + fraction + abbr);
}
}
string IntToStrCommaSep(int integer, string s=""){
if(integer < 0){ s="-"; integer = -integer; }
for(string right = ""; integer >= 1000; integer /= 1000)
right = "," + RJust(integer % 1000, 3, "0") + right;
return(s + integer + right);
}
string RJust(string s, int size, string fill="0"){
while( StringLen(s) < size ) s = fill + s; return(s);
}
To add comments, please log in or register