STR() and VAL() are reciprocal functions for converting numeric values to strings and vice versa. Both process null values correctly, returning nulls.
cReturn = STR( nNumeric [, nLength [, nDecimals ] ] )
nReturn = VAL( cString )|
Parameter |
Value |
Meaning |
|
nNumeric |
Numeric |
The numeric value to be converted. |
|
nLength |
Numeric |
The overall length of the resulting field, including preceding minus signs and any decimal places. Defaults to 10 if not specified. Limited to a maximum of 237. |
|
nDecimals |
Numeric |
Number of decimal places to be returned. If nDecimals is greater than (nLength minus 2), the length takes priority and no more than (nLength minus 2) decimal places are returned. Defaults to zero if not specified. Limited to a maximum of 18. |
|
cString |
Character |
A numeric value expressed in a string. Preceding plus or minus signs recognized. 16-character limit. |
STR() takes a numeric value and returns a character value. Optionally, the length and number of decimal places of the field may be specified. If the length is less than the number of digits to the left of the decimal place, one of two things happens. If the number is less than 10 billion or the specified size is less than seven characters, asterisks are returned. But wait. If the numeric value has 10 digits to the left of the decimal place and the resulting string length is specified as at least seven, one of two things happens. In all cases, a string is returned in scientific notation. However, the string disagrees slightly between VFP 3 and later versions. Both versions are mathematically correct, but the string returned by the later versions more closely resembles what we learned was "scientific notation" in school:
? STR(1234567890123,7) && Returns ".1E+13" in VFP 3
? STR(1234567890123,7) && Returns "1.E+12" in VFP 5 and later
? STR(1234567890123,12) && Returns ".123456E+13" in VFP 3
? STR(1234567890123,12) && Returns "1.23456E+12" in VFP 5 and laterThis can be as useless as asterisks, because the exact value of the number has been lost for display purposes. If you're performing bulk conversions of numeric data to strings, make sure that you check for a return of asterisks or one containing the letter "E".
VAL() returns a number based on its evaluation of the numeric portion of a string. VAL() ignores alphabetic characters after the number, converting VAL("234abc") to 234. VAL() recognizes and correctly parses leading spaces, and plus and minus signs. VAL() also understands scientific notation, properly converting character expressions in the form "xE±z".
Like other functions that depend on settings and symbols that vary by country, VAL() correctly respects the settings of SET("POINT") to display and parse decimal points. If your application is likely to be used with data that may have been saved with another decimal mark, make sure you have a way of detecting this. Similarly, if your users can customize your application to their native settings, you need to bracket code where you assume the setting of POINT.
|
This bug was introduced in VFP 5 and was fixed in VFP 7 Service Pack 1: Under some circumstances, passing VAL() a valid number in scientific notation or passing a character value would crash VFP. |
nHardDriveSize = VAL(SYS(2020))
cPageNum = "Page "+LTRIM(STR(_PAGENO))
lnWrongVal = VAL("123,456") && What's this value?
lcPointSet = SET("POINT") && Preserve the setting
SET POINT TO "." && Set to known value
lnMyVal = VAL("12345.67") && Use it
SET POINT TO lcPointSet && Restore the settingThe first example shows how VAL() can return a numeric value from one of the SYS() Functions, which typically return their values as character strings. The second example shows one of the most common uses of the STR() function—converting the system memory variable _PAGENO, representing the current page being printed, to a string to use as part of your report header or footer. The third example, lnWrongVal, shows a killer mistake. In the U.S., this number is parsed up to the alphabetic comma and is evaluated as exactly 123. In most of Europe, where the POINT is typically a comma and the thousands separator a period, this value has a potentially significant decimal portion. Miscalculations at this level can be disastrous, and a bear to track down. The last example shows an example of the right way to capture the POINT setting, change it, perform your function, and restore it.

