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.1
Decimals: 2.00 Floor: 2.00 NumToStr(): 1.13
Decimals: 3.00 Floor: 2.00 NumToStr(): 1.13
Decimals: 2.999999999999999600000000000000
Using round in NumToStr(): 1.132
Decimals: 4.00 Floor: 4.00 NumToStr(): 1.1321
Decimals: 5.00 Floor: 5.00 NumToStr(): 1.13210
Decimals: 6.00 Floor: 5.00 NumToStr(): 1.13210
Decimals: 5.999999999999999100000000000000
Using round in NumToStr(): 1.132105
Decimals: 7.00 Floor: 7.00 NumToStr(): 1.1321050
Decimals: 8.00 Floor: 8.00 NumToStr(): 1.13210498
Decimals: 9.00 Floor: 8.00 NumToStr(): 1.13210498
Decimals: 8.999999999999998200000000000000
Using round in NumToStr(): 1.132104982
Decimals: 10.00 Floor: 10.00 NumToStr(): 1.1321049823
Decimals: 11.00 Floor: 11.00 NumToStr(): 1.13210498235
Decimals: 12.00 Floor: 11.00 NumToStr(): 1.13210498235
Decimals: 11.999999999999998000000000000000
Using round in NumToStr(): 1.132104982347
Decimals: 13.00 Floor: 12.00 NumToStr(): 1.132104982347
Decimals: 12.999999999999998000000000000000
Using round in NumToStr(): 1.1321049823472
Decimals: 14.00 Floor: 14.00 NumToStr(): 1.13210498234724
Decimals: 15.00 Floor: 14.00 NumToStr(): 1.13210498234724
Decimals: 14.999999999999998000000000000000
Using round in NumToStr(): 1.132104982347239
Decimals: 16.00 Floor: 16.00 NumToStr(): 1.1321049823472389
Decimals: 17.00 Floor: 17.00 NumToStr(): 1.13210498234723890
Decimals: 18.00 Floor: 17.00 NumToStr(): 1.13210498234723890
Decimals: 17.999999999999996000000000000000
Using round in NumToStr(): 1.132104982347238900
Decimals: 19.00 Floor: 19.00 NumToStr(): 1.1321049823472389000
Decimals: 20.00 Floor: 20.00 NumToStr(): 1.13210498234723890000
Decimals: 21.00 Floor: 20.00 NumToStr(): 1.13210498234723890000
Decimals: 20.999999999999996000000000000000
Using round in NumToStr(): 1.132104982347238900000
Decimals: 22.00 Floor: 22.00 NumToStr(): 1.1321049823472389000000
Decimals: 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