##
How can I convert a number to a string when I don"t know the number of decimal places?

SilkTest has two built-in number to string converters - PrintfToString() and Str(number,length,decimals) - but both rely on the user knowing how many decimal places the number to be converted has. The following two functions do not need this knowledge; the first function calculates the exact number of decimal places when the size of the number that will be returned is unknown and the second, simpler, function calculates the exact number of decimal places when the user knows that those decimal places will never exceed a certain length (iPlaces). Both results are used with the Str command options to give the required result.

[ ] //This function will calculate the number of decimal places

[ ] //in a REAL number and return the answer so that the input

[ ] //number can be converted to a string for printing without

[ ] //any loss of precision. Trailing zeroes are stripped.

[-] INTEGER GetDecimalPlaces1(REAL rNumber, INTEGER iDecimals)

[ ]

[ ] REAL rNum2

[ ] REAL rNum1

[ ] REAL rNum3

[ ] REAL rFactor

[ ] REAL rModulo

[ ]

[ ] STRING sDec

[ ]

[ ] sDec=""

[ ]

[ ] rNum1=rNumber

[ ] rNum2=0

[ ] rNum3=0

[ ] rFactor=1

[ ]

[ ] //Use the Str function to truncate the real number

[ ] //and then convert it back again to get just the

[ ] //units figure into rNum2

[ ] sDec=str(rNum1)

[ ] rNum2=val(sDec)

[ ]

[ ] //As the Str truncation rounds up or down, we need to test

[ ] //which way it rounded. If we then subtract the low figure from

[ ] //the high figure we remove the units number (rNum2) and rNum3

[ ] //will have only the decimal places left in it.

[-] if(rNum2>rNum1)

[ ] rNum3=(rNum2-rNum1)

[ ] rNum3=(1-rNum3)

[-] else

[ ] rNum3=(rNum1-rNum2)

[ ]

[ ] //If we now do a modulo on the number, we can get the

[ ] //multiplication factor required to move the decimals

[ ] //to the left of the decimal point. The problem we have

[ ] //here is that we must force 4Test to round down.

[ ] rModulo=1

[-] while(rModulo!=0)

[ ] rFactor=rFactor*10

[ ] rNum1=rNum3*rFactor

[ ] sDec=str(rNum1)

[ ] rNum2=val(sDec)

[-] if(rNum2>rNum1)

[ ] rNum2=rNum2-1

[ ] rModulo=rNum1%rNum2

[ ]

[ ] //Multiply by the factor to move the decimals to the left of the point

[ ] rNum3=rNum3*rFactor

[ ]

[ ] //sNum now contains only the decimal places

[ ] //so a simple len test will tell us how many

[ ] sDec=str(rNum3)

[ ] iDecimals=len(sDec)

[ ] return iDecimals

[ ] //----------------------------------------------------------

[ ] //This second function will return the same result but relies

[ ] //on the user knowing that the decimal places will not exceed

[ ] //a given number (iPlaces). It removes any trailing zeroes if the number

[ ] //of decimal places does not match the maximum allowed number

[-] INTEGER GetDecimalPlaces2(REAL rNumber, INTEGER iDecimals, INTEGER iPlaces)

[ ]

[ ] STRING sDec

[ ] STRING sGet

[ ] INTEGER i

[ ] INTEGER j

[ ]

[ ] sDec=""

[ ] sGet=""

[ ]

[ ] sDec=str(rNumber,1,iPlaces)

[ ] j=Len(sDec)

[-] for(i=j;i>=0;i--)

[ ] sGet=SubStr(sDec,i,1)

[-] if(Right(sGet,1)!="0")

[ ] break

[ ]

[ ] iDecimals=j-i

[ ] return iDecimals

[ ] //----------------------------------------------------------

[ ] //Testcase to drive the GetDecimalPlace functions

[-] testcase GetDecimals () appstate none

[ ] REAL rNum1

[ ]

[ ] STRING sNum

[ ]

[ ] INTEGER iPlaces

[ ] INTEGER iDecs

[ ]

[ ] iPlaces=0

[ ] iDecs=0

[ ]

[ ] rNum1=12345.9876

[ ] print ("Starting number is",rNum1)

[ ]

[ ] //Get the decimal places when the number of

[ ] //decimal places is unknown

[ ] iDecs=GetDecimalPlaces1(rNum1,iDecs)

[ ] print ("With unknown number of decimal places: "+str(rNum1,1,iDecs))

[ ]

[ ] //Get the decimal places when the number of

[ ] //decimal places will not exceed a known figure

[ ] iPlaces=10

[ ] iDecs=GetDecimalPlaces2(rNum1,iDecs,iPlaces)

[ ] sNum=str(rNum1,1,iPlaces-iDecs)

[ ] print ("Number not exceeding 10 decimal places: "+sNum)

The printed results will be:

[-] Testcase GetDecimals - Passed

[ ] Starting number is 12345.987600

[ ] With unknown number of decimal places: 12345.9876

[ ] Number not exceeding 10 decimal places: 12345.9876

See also KB article 21887 - Displaying numbers with separators.