Do we have the equivalents of the IsAlpha, IsUpper, IsLower, and IsNum in QBPE? I have searched but could only find them in C++.
If not, could they be easily implemented? It seems to me that it would be fairly simple, and would be quite useful.
Of all the places on Earth, and all the planets in the Universe, I'd rather live here (Perth, Western Australia.)
Please visit my Website at: http://oldendayskids.blogspot.com/
01-21-2026, 10:45 PM (This post was last modified: 01-21-2026, 10:47 PM by ahenry3068.)
Here's IsNum
Code: (Select All)
Function IsNum% (PassedText As String)
dim text$, temp$
dim special$
dim r$
dim r2$
dim r3$
dim check$
dim I as integer
text$ = PassedText
special$ = UCase$(Left$(text$, 2))
Select Case special$
Case "&H", "&B", "&O"
'check for symbols on right side of value
r3$ = Right$(text$, 3)
Select Case r3$
Case "~&&", "~%%", "~%&" 'unsigned int64, unsigned byte, unsigned offset
text$ = Left$(text$, Len(text$) - 3)
Case Else
r2$ = Right$(text$, 2)
Select Case r2$
Case "~&", "##", "%&", "%%", "~%", "&&" 'unsigned long, float, offset, byte, unsigned integer, int64
text$ = Left$(text$, Len(text$) - 2)
Case Else
r$ = Right$(text$, 1)
Select Case r$
Case "&", "#", "%", "!" 'long, double, integer, single
text$ = Left$(text$, Len(text$) - 1)
End Select
End Select
End Select
check$ = "0123456789ABCDEF"
If special$ = "&O" Then check$ = "01234567"
If special$ = "&B" Then check$ = "01"
temp$ = Mid$(UCase$(text$), 2)
For I = 1 To Len(temp$)
If InStr(check$, Mid$(temp$, I, 1)) = 0 Then Exit For
Next
If I <= Len(temp$) Then IsNum = -1
Case Else
If _Trim$(Str$(Val(text$))) = text$ Then IsNum = -1
End Select
End Function
FUNCTION IsLetter(L as String)
IsLetter = ( ASC(L) >= ASC("A") and ASC(L) <= ASC("Z")) or ( ASC(L) >= ASC("a") and ASC(L) <= ASC("z") )
END FUNCTION
FUNCTION IsWhiteSpace(L as String)
DIM C AS INTEGER
C = ASC(L)
IsWhiteSpace = C=32 or C=9 or C=8 or C=13 or C=10 or C=7
END FUNCTION
FUNCTION IsAlpha(S as String)
DIM TMP AS INTEGER
DIM I AS LONG
TMP = _True
FOR I = 1 to Len(S)
If IsLetter(MID$(S,I,1)) or IsWhiteSpace(MID$(S,I,1)) THEN
_Continue
Else
TMP = _False
Exit For
End If
Next
IsAlpha = TMP
End FUNCTION
01-21-2026, 11:07 PM (This post was last modified: 01-21-2026, 11:09 PM by ahenry3068.)
You should be able to suss out an IsUpper and IsLower by dissecting IsAlpha
or
Code: (Select All)
FUNCTION IsUpperLetter(L as String)
IsUpperLetter = ( ASC(L) >= ASC("A") and ASC(L) <= ASC("Z"))
END FUNCTION
FUNCTION IsLowerLetter(L as String)
IsLowerLetter = ( ASC(L) >= ASC("a") and ASC(L) <= ASC("z") )
END FUNCTION
FUNCTION IsLetter (L as String)
IsLetter = IsLowerLetter(L) or IsUpperLetter(L)
END FUNCTION
FUNCTION IsWhiteSpace(L as String)
DIM C AS INTEGER
C = ASC(L)
IsWhiteSpace = C=32 or C=9 or C=8 or C=13 or C=10 or C=7
END FUNCTION
FUNCTION IsAlpha(S as String)
DIM TMP AS INTEGER
DIM I AS LONG
TMP = _True
FOR I = 1 to Len(S)
If IsLetter(MID$(S,I,1)) or IsWhiteSpace(MID$(S,I,1)) THEN
_Continue
Else
TMP = _False
Exit For
End If
Next
IsAlpha = TMP
End FUNCTION
FUNCTION IsUpper(S as String)
DIM TMP AS INTEGER
DIM I AS LONG
TMP = _True
FOR I = 1 to Len(S)
If IsUpperLetter(MID$(S,I,1)) or IsWhiteSpace(MID$(S,I,1)) THEN
_Continue
Else
TMP = _False
Exit For
End If
Next
IsAlpha = TMP
End FUNCTION
FUNCTION IsLower(S as String)
DIM TMP AS INTEGER
DIM I AS LONG
TMP = _True
FOR I = 1 to Len(S)
If IsLowerLetter(MID$(S,I,1)) or IsWhiteSpace(MID$(S,I,1)) THEN
_Continue
Else
TMP = _False
Exit For
End If
Next
IsAlpha = TMP
End FUNCTION
You do know you can force to Upper or Lower with UCASE$ & LCASE$ .
If I need to do case insensitive or case sensitive comparisons I use these.
I do like the IsNum one. Val by itself is insufficient, so the function must check each character of the string. It is cool that val() can detect some, like &H75, which returns 117 if I remember correctly.
01-22-2026, 12:23 AM (This post was last modified: 01-22-2026, 12:27 AM by ahenry3068.)
(01-22-2026, 12:09 AM)Pete Wrote: Probably stuff I don't need... unless you want to throw in 40 virgins, then I'd be happy to convert to IsNum. If this offended anybody, IsTooBad.
I do like the IsNum one. Val by itself is insufficient, so the function must check each character of the string. It is cool that val() can detect some, like &H75, which returns 117 if I remember correctly.
Pete
The IsNum one is well optimized and one I use quite a bit, It's handy ! The other one's I just threw together on the Spot to show Phil how it could be done.
I knew right away they aren't well optimized. ! I typically don't care much about Is Upper or Is Lower. If I'm doing a comparison that needs to account for case
I usually force the case with UCASE before doing a comparison !
I could optimize it a little by using _orelse instead of or in few of those functions.
(01-22-2026, 12:09 AM)Pete Wrote: Probably stuff I don't need... unless you want to throw in 40 virgins, then I'd be happy to convert to IsNum. If this offended anybody, IsTooBad.
I do like the IsNum one. Val by itself is insufficient, so the function must check each character of the string. It is cool that val() can detect some, like &H75, which returns 117 if I remember correctly.
Pete
The IsNum one is well optimized and one I use quite a bit, It's handy ! The other one's I just threw together on the Spot to show Phil how it could be done.
I knew right away they aren't well optimized. ! I typically don't care much about Is Upper or Is Lower. If I'm doing a comparison that needs to account for case
I usually force the case with UCASE before doing a comparison !
I could optimize it a little by using _orelse instead of or in few of those functions.
Thanks both for that, but I already use similar constructs when I need them - and yes, I am aware of UCase$ and LCase$, and use these regularly.
What I meant was, could those functions be implemented as a keyword. I know, that's lazy, but if it speeds up or simplifies coding I think it would be worthwhile.
Of all the places on Earth, and all the planets in the Universe, I'd rather live here (Perth, Western Australia.)
Please visit my Website at: http://oldendayskids.blogspot.com/
'First look for manually assigned types
r1$ = Right$(temp$, 1): r = 1
r2$ = Left$(Right$(temp$, 2), 1) Select Case r1$ Case"`"
TestFor = 1'bit Case"%" If r2$ = "%"Then
r = 2
TestFor = 2'byte Else
TestFor = 3'integer End If Case"&"'long, int64, offset If r2$ = "&"Then
r = 2
TestFor = 5'int64 ElseIf r2$ = "%"Then
r = 2
TestFor = 9'offset Else
TestFor = 4'long End If Case"!"'single
TestFor = 6 Case"#"'double, float If r2$ = "#"Then
r = 2
TestFor = 8'float Else
TestFor = 7'double End If Case Else'there's no set type
TestFor = 0
r = 0 End Select
'Test for easy integers 'First check for positive/negative values; flag for invalid cases of multiple negation. IfMid$(temp$, 1, 1) = "-"Then
negative = -1: temp$ = Mid$(temp$, 2) 'strip off the initial negative ElseIfMid$(temp$, 1, 1) = "+"Then
temp$ = Mid$(temp$, 2) 'strip off the initial positive End If
For i = 1ToLen(temp$) IfMid$(temp$, i, 1) = "-"Then minus = minus + 1 IfMid$(temp$, i, 1) = "+"Then plus = plus + 1 IfMid$(temp$, i, 1) = "."Then period = period + 1'Go ahead and check for multiple periods while we're at it. IfMid$(temp$, i, 1) = "E"OrMid$(temp$, i, 1) = "D"Then
Exponent = Exponent + 1 IfMid$(temp$, i + 1, 1) = "-"OrMid$(temp$, i + 1, 1) = "+1"Then ExponentSign = -1 End If Next
If period = 0And Exponent = 0Then'we should only have integers to process For i = 1ToLen(temp$)
t$ = Mid$(temp$, i, 1) If t$ < "0"Or t$ > "9"Then NumErr$ = NumErr$ + "Invalid Character (" + t$ + ") encountered. ": Exit Function Next GoTo evaluateintegers End If
'At this point forward, we should only have REAL numbers to process
If Exponent > 1Then NumErr$ = NumErr$ + "Multiple E/D exponent characters in string. ": Exit Function
If ExponentSign = 0Then If minus Then NumErr$ = NumErr$ + "Multiple negative signs (-) encountered. ": Exit Function If plus Then NumErr$ = NumErr$ + "Multiple negative signs (-) encountered. ": Exit Function Else If minus > 1Then NumErr$ = NumErr$ + "Multiple negative signs (-) encountered. ": Exit Function If plus > 1Then NumErr$ = NumErr$ + "Multiple negative signs (-) encountered. ": Exit Function End If
If period > 1Then NumErr$ = NumErr$ + "Multiple decimal points (.) encountered. ": Exit Function
For i = 1ToLen(temp$)
t$ = Mid$(temp$, i, 1) Select Case t$ Case"0"To"9", "-", "+", ".", "D", "E"'we should have validated all these characters earlier Case Else'so anything else is invalid
NumErr$ = NumErr$ + "Invalid Character (" + t$ + ") encountered. ": Exit Function End Select Next
'first compare for all types IfInt(t##) = t## Then If t## = -1Or t## = 0Then TempNum = TempNum Or32'signed bit If t## >= -128And t## <= 127Then TempNum = TempNum Or64'signed byte If t## >= -32768And t## <= 32767Then TempNum = TempNum Or128'signed integer If t## >= -2147483648And t## <= 2147483647Then TempNum = TempNum Or256'signed long If t## >= -9223372036854775808And t## <= 9223372036854775807Then
TempNum = TempNum Or512'signed integer64
TempNum = TempNum Or16384'signed offset End If If t## = 1Or t## = 0Then TempNum = TempNum Or1'unsigned bit If t## >= 0And t## <= 255Then TempNum = TempNum Or2'unsigned byte If t## >= 0And t## <= 65535Then TempNum = TempNum Or4'unsigned integer If t## >= 0And t## <= 4294967295Then TempNum = TempNum Or8'unsigned long If t## >= 0And t## <= 18446744073709551615Then
TempNum = TempNum Or16'unsigned integer64
TempNum = TempNum Or8192'unsigned offset End If End If
If t## >= -2.802597D45And t## <= 3.402823D+38Then
TempNum = TempNum Or1024'single End If If t## >= -4.490656458412465E324And t## <= 1.797693134862310E+308Then TempNum = TempNum Or2048'double If t## >= -1.18E4932And t## <= 1.18E+4932Then TempNum = TempNum Or4096'float
If r Then'we have specific suffix; only decide if the value is valid for it
TempNum = 0 IfNot Unsigned Then'unsigned Select Case TestFor Case1 If t## = -1Or t## = 0Then TempNum = 32'signed bit Case2 If t## >= -128And t## <= 127Then TempNum = 64'signed byte Case3 If t## >= -32768And t## <= 32767Then TempNum = 128'signed integer Case4 If t## >= -2147483648And t## <= 2147483647Then TempNum = 256'signed long Case5, 9 If t## >= -9223372036854775808And t## <= 9223372036854775807Then If TestFor = 5Then
TempNum = 512'signed integer64 Else
TempNum = 16384'signed offset End If End If Case6 If t## >= -2.802597E-45And t## <= 3.402823E+38Then TempNum = 1024'single Case7 If t## >= -4.490656458412465E-324And t## <= 1.797693134862310E+308Then TempNum = 2048'double Case9 If t## >= -1.18E-4932And t## <= 1.18E+4932Then TempNum = 4096'float End Select Else Select Case TestFor Case1 If t## = 0Or t## = 1Then TempNum = 1'unsigned bit Case2 If t## >= 0And t## <= 255Then TempNum = 2'unsigned byte Case3 If t## >= 0And t## <= 65535Then TempNum = 4'unsigned integer Case4 If t## >= 0And t## <= 4294967295Then TempNum = 8'unsigned long Case5, 9 If t## >= 0And t## <= 18446744073709551615Then If TestFor = 5Then
TempNum = 16'unsigned integer64 Else
TempNum = 8192'unsigned offset End If End If End Select End If If TempNum = 0Then NumErr$ = "Invalid Suffix. " End If NumType = TempNum End Function
The above makes these functions work for you. It also tells you what numeric TYPE a number is, if you're interested in that bit of information as well, so you can not only determine if it's a valid number, but if it's a valid _BYTE or whatnot.
Function IsNum% (PassedText As String)
dim text$, temp$
dim special$
dim r$
dim r2$
dim r3$
dim check$
dim I as integer
text$ = PassedText
special$ = UCase$(Left$(text$, 2))
Select Case special$
Case "&H", "&B", "&O"
'check for symbols on right side of value
r3$ = Right$(text$, 3)
Select Case r3$
Case "~&&", "~%%", "~%&" 'unsigned int64, unsigned byte, unsigned offset
text$ = Left$(text$, Len(text$) - 3)
Case Else
r2$ = Right$(text$, 2)
Select Case r2$
Case "~&", "##", "%&", "%%", "~%", "&&" 'unsigned long, float, offset, byte, unsigned integer, int64
text$ = Left$(text$, Len(text$) - 2)
Case Else
r$ = Right$(text$, 1)
Select Case r$
Case "&", "#", "%", "!" 'long, double, integer, single
text$ = Left$(text$, Len(text$) - 1)
End Select
End Select
End Select
check$ = "0123456789ABCDEF"
If special$ = "&O" Then check$ = "01234567"
If special$ = "&B" Then check$ = "01"
temp$ = Mid$(UCase$(text$), 2)
For I = 1 To Len(temp$)
If InStr(check$, Mid$(temp$, I, 1)) = 0 Then Exit For
Next
If I <= Len(temp$) Then IsNum = -1
Case Else
If _Trim$(Str$(Val(text$))) = text$ Then IsNum = -1
End Select
End Function
Note that this can fail with scientific notation values.