# NumToStr() displays an incorrect number of Decimals [Solved]

Questions about MultiCharts and user contributed studies.
JoshM
Posts: 2099
Joined: 20 May 2011
Location: The Netherlands
Has thanked: 1527 times
Been thanked: 1494 times
Contact:

### NumToStr() displays an incorrect number of Decimals [Solved]

Marina Pashkova wrote:The number of decimals for a symbol is regulated through the settings in Quote Manager->Edit Symbol->Settings - Price Scale.

I came across this topic when searching for a way to return the number of decimals in a number (for example 5 for 1.56897 and three for 154.025). Below is how I solved this, and perhaps this is of use to someone else.

Code: Select all

`if LastBarOnChart_s and barstatus = 2 then begin   value34 = 1 / PriceScale;         // returns pricescale with decimals, in this case 0.001   value35 = 0;      while value35 = 0 begin      value40 = value34 * 10;         // Multiply by 10 to step-by-step remove the decimals      value50 = value50 + 1;         // Counter with number of multiplications      if FracPortion(value40) = 0 then         value35 = 1;               // If there aren't any Fractions left; break out the while loop      value34 = value40;            // Set value 40 to the new value   end;   Print("The number ", (1/PriceScale):0:4, " has ", value50, " decimals.");end;`

..which returns:

Code: Select all

`The number 0.0010 has    3.00 decimals.`

Though I am wondering: perhaps there is a more efficient way to do this?

Regards,
Josh
Last edited by JoshM on 09 Sep 2011, edited 1 time in total.

TJ
Posts: 6869
Joined: 29 Aug 2006
Location: Global Citizen
Has thanked: 984 times
Been thanked: 1976 times

### Re: How can you remove the 3 decimal places in MC with the E

JoshM wrote:
Marina Pashkova wrote:The number of decimals for a symbol is regulated through the settings in Quote Manager->Edit Symbol->Settings - Price Scale.

I came across this topic when searching for a way to return the number of decimals in a number (for example 5 for 1.56897 and three for 154.025). Below is how I solved this, and perhaps this is of use to someone else.

Code: Select all

`if LastBarOnChart_s and barstatus = 2 then begin   value34 = 1 / PriceScale;         // returns pricescale with decimals, in this case 0.001   value35 = 0;      while value35 = 0 begin      value40 = value34 * 10;         // Multiply by 10 to step-by-step remove the decimals      value50 = value50 + 1;         // Counter with number of multiplications      if FracPortion(value40) = 0 then         value35 = 1;               // If there aren't any Fractions left; break out the while loop      value34 = value40;            // Set value 40 to the new value   end;   Print("The number ", (1/PriceScale):0:4, " has ", value50, " decimals.");end;`

..which returns:

Code: Select all

`The number 0.0010 has    3.00 decimals.`

Though I am wondering: perhaps there is a more efficient way to do this?

Regards,
Josh

you can reduce the calculation to this one line:

Code: Select all

`decimal = Log( PriceScale ) / Log(10) ;`
These users thanked the author TJ for the post (total 5):
JoshMRobotManStan BokovNW27arjfca

JoshM
Posts: 2099
Joined: 20 May 2011
Location: The Netherlands
Has thanked: 1527 times
Been thanked: 1494 times
Contact:

### Re: How can you remove the 3 decimal places in MC with the E

Thanks TJ! Now that's a reduction!

Have a nice weekend,

Regards,
Josh

Stan Bokov
Posts: 963
Joined: 18 Dec 2009
Has thanked: 367 times
Been thanked: 300 times

### Re: How can you remove the 3 decimal places in MC with the E

TJ wrote:you can reduce the calculation to this one line:

Code: Select all

`decimal = Log(PriceScale) / Log(10) ;`

Nice...
These users thanked the author Stan Bokov for the post:
TJ

JoshM
Posts: 2099
Joined: 20 May 2011
Location: The Netherlands
Has thanked: 1527 times
Been thanked: 1494 times
Contact:

### Re: How can you remove the 3 decimal places in MC with the E

TJ wrote:you can reduce the calculation to this one line:

Code: Select all

`decimal = Log(PriceScale) / Log(10) ;`

Hm, if I calculate the decimals and use NumToStr() to print these, I get for certain instruments (for example, USD/JPY) wrong results, even though the formula quoted above does work correctly.

Code:

Code: Select all

`variables: numOfDeci(0);numOfDeci = Log(PriceScale) / Log(10);if LastBarOnChart_s = true then begin   Print(getsymbolname, " Close: ", NumToStr(Close, 10), " decimals: ", numOfDeci);      Print(Spaces(2), "PriceScale: ", PriceScale);   Print(Spaces(2), "Close with calculated Decimals: ", NumToStr(Close, numOfDeci));end;`

Which gives the following output:

Code: Select all

`FGBM Close: 115.9800000000 decimals:    2.00  PriceScale:  100.00  Close with calculated Decimals: 115.98USD/JPY Close: 78.0290000000 decimals:    3.00  PriceScale: 1000.00  Close with calculated Decimals: 78.03EUR/USD Close: 1.4475400000 decimals:    5.00  PriceScale: 100000.00  Close with calculated Decimals: 1.44754`

As you can see, the number of decimals for the USD/JPY are calculated as 3, yet printed with 2 (output should be 78.029, not 78.03).

What's going wrong here?

Regards,
Josh

JoshM
Posts: 2099
Joined: 20 May 2011
Location: The Netherlands
Has thanked: 1527 times
Been thanked: 1494 times
Contact:

### SOLVED

JoshM wrote:The only way I can explain this NumToStr() behaviour is saying that it's a 'bug' - which actually means that I'm just out of ways to test/dissect this behaviour.
[...]
Anyone got an idea?

Well, it's not a bug and I got it solved (see below), but could have saved a lot of time spent "debugging" this behaviour if I knew that:

NumToStr() uses Floor() to determine the number of decimals and not Round().

It's not in the manual or help, but well, at least now we know that.

Example:
Code:

Code: Select all

`variables: numDeci(0), numDeciToStr(""), myValue(0), remainderStr("");once cleardebug;if LastBarOnChart_s = true then begin   value1 = 1.132104982347238974239847692834;   value3 = 10;      while value3 <= 100000000000000000000000 begin         numDeci = Log(value3) / Log(10);            Print("Decimals: ", numDeci, "  Floor: ", Floor(numDeci), "     NumToStr(): ", NumToStr(value1, numDeci));                     // If there's a difference between the values, print these to string with the maximum number of decimals      if numDeci <> Floor(numDeci) then begin               Print(Spaces(3), "Decimals: ", NumToStr(numDeci, 30));         Print(Spaces(3), "Using round in NumToStr(): ", NumToStr(value1, Round(numDeci, 0)));      end;         value3 = value3 * 10;   end;end;`

Which gives the following output:

Code: Select all

`Decimals:    1.00  Floor:    1.00     NumToStr(): 1.1Decimals:    2.00  Floor:    2.00     NumToStr(): 1.13Decimals:    3.00  Floor:    2.00     NumToStr(): 1.13   Decimals: 2.999999999999999600000000000000   Using round in NumToStr(): 1.132Decimals:    4.00  Floor:    4.00     NumToStr(): 1.1321Decimals:    5.00  Floor:    5.00     NumToStr(): 1.13210Decimals:    6.00  Floor:    5.00     NumToStr(): 1.13210   Decimals: 5.999999999999999100000000000000   Using round in NumToStr(): 1.132105Decimals:    7.00  Floor:    7.00     NumToStr(): 1.1321050Decimals:    8.00  Floor:    8.00     NumToStr(): 1.13210498Decimals:    9.00  Floor:    8.00     NumToStr(): 1.13210498   Decimals: 8.999999999999998200000000000000   Using round in NumToStr(): 1.132104982Decimals:   10.00  Floor:   10.00     NumToStr(): 1.1321049823Decimals:   11.00  Floor:   11.00     NumToStr(): 1.13210498235Decimals:   12.00  Floor:   11.00     NumToStr(): 1.13210498235   Decimals: 11.999999999999998000000000000000   Using round in NumToStr(): 1.132104982347Decimals:   13.00  Floor:   12.00     NumToStr(): 1.132104982347   Decimals: 12.999999999999998000000000000000   Using round in NumToStr(): 1.1321049823472Decimals:   14.00  Floor:   14.00     NumToStr(): 1.13210498234724Decimals:   15.00  Floor:   14.00     NumToStr(): 1.13210498234724   Decimals: 14.999999999999998000000000000000   Using round in NumToStr(): 1.132104982347239Decimals:   16.00  Floor:   16.00     NumToStr(): 1.1321049823472389Decimals:   17.00  Floor:   17.00     NumToStr(): 1.13210498234723890Decimals:   18.00  Floor:   17.00     NumToStr(): 1.13210498234723890   Decimals: 17.999999999999996000000000000000   Using round in NumToStr(): 1.132104982347238900Decimals:   19.00  Floor:   19.00     NumToStr(): 1.1321049823472389000Decimals:   20.00  Floor:   20.00     NumToStr(): 1.13210498234723890000Decimals:   21.00  Floor:   20.00     NumToStr(): 1.13210498234723890000   Decimals: 20.999999999999996000000000000000   Using round in NumToStr(): 1.132104982347238900000Decimals:   22.00  Floor:   22.00     NumToStr(): 1.1321049823472389000000Decimals:   23.00  Floor:   22.00     NumToStr(): 1.1321049823472389000000   Decimals: 22.999999999999996000000000000000   Using round in NumToStr(): 1.13210498234723890000000`

Solution:
When using calculated values as input for the NumToStr() function, use Round() to ensure that the correct value gets passed, for example:

Code: Select all

`NumToStr(1.1255445484, Round(myValue, 0));`

Btw, I also noticed that NumToStr() has an limitation of 30 decimals - it does accept higher number of decimals, but the string that subsequently gets generated will only have 30 numbers behind the dot.

Regards,
Josh

Return to “MultiCharts”