Is there a way to check if an expression returns numeric?
-
- User
- Posts: 59
- Joined: Sun Jul 21, 2013 8:30 am
Is there a way to check if an expression returns numeric?
Hi,
Is it possible to take a string, like "5 * 23", and 1) find out if it represents a numeric expression, and 2) Perform the calculation, if it's not already a single value?
I have an IsNumeric function from the web, but it doesn't work for arithmetic expressions.
Is it possible to take a string, like "5 * 23", and 1) find out if it represents a numeric expression, and 2) Perform the calculation, if it's not already a single value?
I have an IsNumeric function from the web, but it doesn't work for arithmetic expressions.
Re: Is there a way to check if an expression returns numeric
Try this:
It returns "ERROR" if it is not a valid expression.
Code: Select all
XIncludeFile "Evaluate.pbi" ; http://danilo.purearea.net/EvaluateExpression.zip
Debug Evaluate("5 * 23")
Debug Evaluate("some text")
Re: Is there a way to check if an expression returns numeric
With database:
Code: Select all
Enumeration
#Database
EndEnumeration
Procedure.f Evaluate(String.s, X.f=0)
Protected Result.s
If DatabaseQuery(#Database, ReplaceString("SELECT ("+String+")", "x", StrF(X)))
If NextDatabaseRow(#Database)
Result = GetDatabaseString(#Database, 0)
EndIf
FinishDatabaseQuery(#Database)
ProcedureReturn ValF(Result)
Else
ProcedureReturn NaN()
EndIf
EndProcedure
UseSQLiteDatabase()
OpenDatabase(#Database, ":memory:", "", "", #PB_Database_SQLite)
Debug Evaluate("1 + 2 * 3")
Debug Evaluate("x+18/(x*x)", 3)
Debug Evaluate("374*4+7*(83+99)-3*128")
Debug Evaluate("some text")
CloseDatabase(#Database)
PB 6.01 ― Win 10, 21H2 ― Ryzen 9 3900X, 32 GB ― NVIDIA GeForce RTX 3080 ― Vivaldi 6.0 ― www.unionbytes.de
Lizard - Script language for symbolic calculations and more ― Typeface - Sprite-based font include/module
Lizard - Script language for symbolic calculations and more ― Typeface - Sprite-based font include/module
-
- User
- Posts: 59
- Joined: Sun Jul 21, 2013 8:30 am
Re: Is there a way to check if an expression returns numeric
Cool, thanks.Danilo wrote:Try this:It returns "ERROR" if it is not a valid expression.Code: Select all
XIncludeFile "Evaluate.pbi" ; http://danilo.purearea.net/EvaluateExpression.zip Debug Evaluate("5 * 23") Debug Evaluate("some text")
It also returns "0" if it's a string without spaces. So if you try
sTestString = Evaluate( "what" )
, sTestString will contain "0".
If
sTestString = Evaluate( "What the...?" )
, then it returns "ERROR"
, as you mentioned.
I can work with that, easily. Thanks, Danilo.
-
- User
- Posts: 59
- Joined: Sun Jul 21, 2013 8:30 am
Re: Is there a way to check if an expression returns numeric
STARGÅTE wrote:With database:Code: Select all
Enumeration #Database EndEnumeration Procedure.f Evaluate(String.s, X.f=0) Protected Result.s If DatabaseQuery(#Database, ReplaceString("SELECT ("+String+")", "x", StrF(X))) If NextDatabaseRow(#Database) Result = GetDatabaseString(#Database, 0) EndIf FinishDatabaseQuery(#Database) ProcedureReturn ValF(Result) Else ProcedureReturn NaN() EndIf EndProcedure UseSQLiteDatabase() OpenDatabase(#Database, ":memory:", "", "", #PB_Database_SQLite) Debug Evaluate("1 + 2 * 3") Debug Evaluate("x+18/(x*x)", 3) Debug Evaluate("374*4+7*(83+99)-3*128") Debug Evaluate("some text") CloseDatabase(#Database)
Huh. Didn't even think of getting a db result, that way. Might come in handy, thanks.
Re: Is there a way to check if an expression returns numeric
Please re-download EvaluateExpression.zipPBExplorer12 wrote:Danilo wrote:Cool, thanks.
It also returns "0" if it's a string without spaces. So if you try
sTestString = Evaluate( "what" )
, sTestString will contain "0".
If
sTestString = Evaluate( "What the...?" )
, then it returns "ERROR"
, as you mentioned.
I can work with that, easily. Thanks, Danilo.
Added #evalError_VariableNotDefined error, so Evaluate("what") returns "ERROR". You can change this behavior in the following procedure:
Code: Select all
Procedure.s __getEvaluateVariable(name.s)
If FindMapElement(EvaluateVariables(),name)
ProcedureReturn Trim(EvaluateVariables())
EndIf
;ProcedureReturn "0" ; unknown variables = 0
ProcedureReturn "ERROR" ; unknown variables = ERROR -> #evalError_VariableNotDefined
EndProcedure
Re: Is there a way to check if an expression returns numeric
Here's a function I've successfully used for quite a while:
Code: Select all
Procedure.i IsNumeric(num$) ; AKJ 07-Mar-11
; Tests whether the given value is purely numeric
; If an exponent is present, it will never be classed as a integer
; A number like 5.00 will be classed as an integer
; Return: -1 if a floating-point number 1 if an integer 0 otherwise
Protected dp, ep, exp$="", signs, status
Select CountString(num$, ".") ; Number of decimal points
Case 0: status = 1 ; Potentially an integer
Case 1: status = -1 ; Potentially a float
Default: ProcedureReturn 0 ; Not a number
EndSelect
; See if an exponent is present
ep = FindString(UCase(num$), "E", 1)
If ep ; If an exponent
status = -1 ; Actually a float
exp$ = Mid(num$, ep+1) ; Exponent
num$ = Left(num$, ep-1) ; Mantissa
; Count and remove leading exponent +/- signs
signs = 0
While Left(exp$,1)="+" Or Left(exp$,1)="-"
signs + 1: exp$ = Mid(exp$, 2)
Wend
If signs>1: ProcedureReturn 0: EndIf ; Text
exp$ = LTrim(exp$, "0") ; Remove leading exponent zeros
If Str(Val(exp$))<>exp$: ProcedureReturn 0: EndIf ; Text
EndIf
; Count and remove leading mantissa +/- signs
signs = 0
While Left(num$,1)="+" Or Left(num$,1)="-"
signs + 1: num$ = Mid(num$, 2)
Wend
If signs>1: ProcedureReturn 0: EndIf ; Text
dp = FindString(num$, ".", 1) ; Location of any decimal point
If dp
If exp$+RemoveString(Mid(num$, dp+1), "0")="": status = 1: EndIf ; Integer if fractional part is zero
num$ = RemoveString(num$, ".") ; Remove decimal point
EndIf
If num$="": ProcedureReturn 0: EndIf ; Null string
num$ = Trim(num$, "0") ; ; Remove outer mantissa zeros
; Ensure the mantissa is purely numeric
If num$ And (Str(Val(num$))<>num$): status = 0: EndIf ; Use quad precision ???
ProcedureReturn status
EndProcedure
; Examples:
Debug IsNumeric("00") ; 1
Debug IsNumeric("0.0") ; 1
Debug IsNumeric("X") ; 0
Debug IsNumeric("E") ; 0
Debug IsNumeric(".") ; 0
Debug IsNumeric("") ; 0
Debug IsNumeric("0") ; 1
Debug IsNumeric("1"); 1
Debug IsNumeric(".0"); 1
Debug IsNumeric(".1") ; -1
Debug IsNumeric("0.1"); -1
Debug IsNumeric("1.0") ; 1
Debug IsNumeric("1.1") ; -1
Debug IsNumeric("0.") ; 1
Debug IsNumeric("1.") ; 1
Debug IsNumeric("-5.1E-7") ; -1
Debug IsNumeric("-5.0E-7") ; -1
Debug IsNumeric("-5E-7") ; -1
Debug IsNumeric("-E-7") ; 0
Debug IsNumeric("56789") ; 1
Debug IsNumeric("-56.789") ; -1
Anthony Jordan
-
- User
- Posts: 59
- Joined: Sun Jul 21, 2013 8:30 am
Re: Is there a way to check if an expression returns numeric
Danilo wrote:Please re-download EvaluateExpression.zipPBExplorer12 wrote:Danilo wrote:Cool, thanks.
It also returns "0" if it's a string without spaces. So if you try
sTestString = Evaluate( "what" )
, sTestString will contain "0".
If
sTestString = Evaluate( "What the...?" )
, then it returns "ERROR"
, as you mentioned.
I can work with that, easily. Thanks, Danilo.
Added #evalError_VariableNotDefined error, so Evaluate("what") returns "ERROR". You can change this behavior in the following procedure:Code: Select all
Procedure.s __getEvaluateVariable(name.s) If FindMapElement(EvaluateVariables(),name) ProcedureReturn Trim(EvaluateVariables()) EndIf ;ProcedureReturn "0" ; unknown variables = 0 ProcedureReturn "ERROR" ; unknown variables = ERROR -> #evalError_VariableNotDefined EndProcedure
Works great, thanks.
-
- User
- Posts: 59
- Joined: Sun Jul 21, 2013 8:30 am
Re: Is there a way to check if an expression returns numeric
Thanks, akj.akj wrote:Here's a function I've successfully used for quite a while:Code: Select all
Procedure.i IsNumeric(num$) ; AKJ 07-Mar-11 ; Tests whether the given value is purely numeric ; If an exponent is present, it will never be classed as a integer ; A number like 5.00 will be classed as an integer ; Return: -1 if a floating-point number 1 if an integer 0 otherwise Protected dp, ep, exp$="", signs, status Select CountString(num$, ".") ; Number of decimal points Case 0: status = 1 ; Potentially an integer Case 1: status = -1 ; Potentially a float Default: ProcedureReturn 0 ; Not a number EndSelect ; See if an exponent is present ep = FindString(UCase(num$), "E", 1) If ep ; If an exponent status = -1 ; Actually a float exp$ = Mid(num$, ep+1) ; Exponent num$ = Left(num$, ep-1) ; Mantissa ; Count and remove leading exponent +/- signs signs = 0 While Left(exp$,1)="+" Or Left(exp$,1)="-" signs + 1: exp$ = Mid(exp$, 2) Wend If signs>1: ProcedureReturn 0: EndIf ; Text exp$ = LTrim(exp$, "0") ; Remove leading exponent zeros If Str(Val(exp$))<>exp$: ProcedureReturn 0: EndIf ; Text EndIf ; Count and remove leading mantissa +/- signs signs = 0 While Left(num$,1)="+" Or Left(num$,1)="-" signs + 1: num$ = Mid(num$, 2) Wend If signs>1: ProcedureReturn 0: EndIf ; Text dp = FindString(num$, ".", 1) ; Location of any decimal point If dp If exp$+RemoveString(Mid(num$, dp+1), "0")="": status = 1: EndIf ; Integer if fractional part is zero num$ = RemoveString(num$, ".") ; Remove decimal point EndIf If num$="": ProcedureReturn 0: EndIf ; Null string num$ = Trim(num$, "0") ; ; Remove outer mantissa zeros ; Ensure the mantissa is purely numeric If num$ And (Str(Val(num$))<>num$): status = 0: EndIf ; Use quad precision ??? ProcedureReturn status EndProcedure ; Examples: Debug IsNumeric("00") ; 1 Debug IsNumeric("0.0") ; 1 Debug IsNumeric("X") ; 0 Debug IsNumeric("E") ; 0 Debug IsNumeric(".") ; 0 Debug IsNumeric("") ; 0 Debug IsNumeric("0") ; 1 Debug IsNumeric("1"); 1 Debug IsNumeric(".0"); 1 Debug IsNumeric(".1") ; -1 Debug IsNumeric("0.1"); -1 Debug IsNumeric("1.0") ; 1 Debug IsNumeric("1.1") ; -1 Debug IsNumeric("0.") ; 1 Debug IsNumeric("1.") ; 1 Debug IsNumeric("-5.1E-7") ; -1 Debug IsNumeric("-5.0E-7") ; -1 Debug IsNumeric("-5E-7") ; -1 Debug IsNumeric("-E-7") ; 0 Debug IsNumeric("56789") ; 1 Debug IsNumeric("-56.789") ; -1