[futurebasic] Re: [FB] FN IsNumeric

Message: < previous - next > : Reply : Subscribe : Cleanse
Home   : October 2001 : Group Archive : Group : All Groups

From: Robert Purves <robert.purves@...>
Date: Sun, 28 Oct 2001 14:04:08 +1300
>Some programming languages have an IsNumeric function that allows a
>programmer to test a string to see whether it contains only numeric
>characters.
>
>The following FN IsNumeric is coded to test a string in the same way
>as IsNumeric in VB, it allows one decimal point to pass in a string
>and still be equated as numeric. The test will fail if more than one
>decimal point is entered, or if the string contains characters other
>than numerals.


Your function does not understand signs or exponential notation, nor does it acknowledge that leading/trailing spaces are "harmless extras".  Something more elaborate is needed, given the wide range of numeric forms that can be understood by FB^3's val function. Try this: 


'----------------------------------
local fn IsNumeric( s as str255 )
// return _zTrue if s represents a number, else _false
dim pntr    as ptr
dim endPtr  as ptr
dim ch      as long
dim numeric as boolean
dim digit   as boolean

pntr    = @s + 1
endPtr  = pntr + s[0] - 1
numeric = _false
if ( pntr <= endPtr ) then ch = pntr.nil`` : pntr++ else exit fn
while ( ch == _" " )
if ( pntr <= endPtr ) then ch = pntr.nil`` : pntr++ else exit fn
wend // ignore leading spaces
long if ( ch == _"+" ) or ( ch == _"-" )
if ( pntr <= endPtr ) then ch = pntr.nil`` : pntr++ else exit fn
end if // ignore leading sign
digit = _false
while ( ch >= _"0" ) and ( ch <= _"9" ) // eat digits
digit = _zTrue
if ( pntr <= endPtr ) then ch = pntr.nil`` : pntr++ else ch = -1
wend
long if digit
long if ( ch == _"." )
if ( pntr <= endPtr ) then ch = pntr.nil`` : pntr++ else ch = -1
while ( ch >= _"0" ) and ( ch <= _"9" ) // eat digits
if ( pntr <= endPtr ) then ch = pntr.nil`` : pntr++ else ch = -1
wend // don't care if none
end if
xelse
long if ( ch == _"." )
if ( pntr <= endPtr ) then ch = pntr.nil`` : pntr++ else ch = -1
digit = _false
while ( ch >= _"0" ) and ( ch <= _"9" ) // eat digits
digit = _zTrue
if ( pntr <= endPtr ) then ch = pntr.nil`` : pntr++ else ch = -1
wend
if ( digit == _false ) then exit fn // no digits before/after point
xelse
exit fn
end if
end if
long if ( ch == _"E" ) or ( ch == _"e" ) // exponent
if ( pntr <= endPtr ) then ch = pntr.nil`` : pntr++ else ch = -1
long if ( ch == _"+" ) or ( ch == _"-" )
if ( pntr <= endPtr ) then ch = pntr.nil`` : pntr++ else ch = -1
end if
digit = _false
while ( ch >= _"0" ) and ( ch <= _"9" ) // eat digits
digit = _zTrue
if ( pntr <= endPtr ) then ch = pntr.nil`` : pntr++ else ch = -1
wend
if ( digit == _false ) then exit fn // no digits after exp
end if
while ( ch == _" " )
if ( pntr <= endPtr ) then ch = pntr.nil`` : pntr++ else ch = -1
wend // eat spaces at end
numeric = ( ch == -1 )
end fn = numeric


local fn StringTest( s as str255 )
print s,
if ( fn IsNumeric( s ) == _false ) then print "not ";
print "numeric",
print val( s )
end fn

print "String", "Status", "Value"
print
fn StringTest( "12345678901234" )
fn StringTest( "12365658657.56" )
fn StringTest( "123a5658654527" )
fn StringTest( "1243.65658.657" )
fn StringTest( "abcdefghijklmn" )
fn StringTest( "1xY12345skf.22" )
fn StringTest( "-1" )
fn StringTest( "+1" )
fn StringTest( ".1" )
fn StringTest( "3." )
fn StringTest( "" )
fn StringTest( "." )
fn StringTest( "-1e+22" )
fn StringTest( "+1e-22" )
fn StringTest( "-1e-+22" )
fn StringTest( "-.1e3" )
fn StringTest( "-.1e.3" )
fn StringTest( "   4E41    " )
fn StringTest( "   4E4 1   " )
fn StringTest( "+" )

#if ndef _defaultRuntime
print
print "Click mouse to end
do
until fn Button
#endif
'----------------------------------



Robert P.