Inspired by the topic here:
https://www.qb64.org/forum/index.php?topic=896.0 ("Does a Is Number function exist in QB64?")
DATA "123a.3","-123.456","--234","1.23E15","123","dogfood","678.965","54678","-987134","1E15" DATA "&HFF","&B1001111","&O17","&HFF&&","&B12000222","1.E-12"
PRINT "TEST #"; i;
": "; test
(i
) + " " result = NumType(test(i))
NumErr$ = "": NumType = 0
'First look for manually assigned types
TestFor = 1 'bit
r = 2
TestFor = 2 'byte
TestFor = 3 'integer
CASE "&" 'long, int64, offset r = 2
TestFor = 5 'int64
r = 2
TestFor = 9 'offset
TestFor = 4 'long
TestFor = 6
r = 2
TestFor = 8 'float
TestFor = 7 'double
TestFor = 0
r = 0
temp$
= LEFT$(temp$
, LEN(temp$
) - r
) 'strip off the type symbol
'check for valid prefixes
NumErr$ = NumErr$ + "Invalid Character (" + t$ + ") encountered. "
CASE "0", "1" 'only valid bit characters NumErr$ = NumErr$ + "Invalid Character (" + t$ + ") encountered. "
CASE "0" TO "7" 'only valid oct characters NumErr$ = NumErr$ + "Invalid Character (" + t$ + ") encountered. "
'Test for easy integers
'First check for positive/negative values; flag for invalid cases of multiple negation.
negative
= -1: temp$
= MID$(temp$
, 2) 'strip off the initial negative temp$
= MID$(temp$
, 2) 'strip off the initial positive
IF MID$(temp$
, i
, 1) = "." THEN period
= period
+ 1 'Go ahead and check for multiple periods while we're at it. Exponent = Exponent + 1
IF MID$(temp$
, i
+ 1, 1) = "-" OR MID$(temp$
, i
+ 1, 1) = "+1" THEN ExponentSign
= -1
IF period
= 0 AND Exponent
= 0 THEN 'we should only have integers to process IF t$
< "0" OR t$
> "9" THEN NumErr$
= NumErr$
+ "Invalid Character (" + t$
+ ") encountered. ":
EXIT FUNCTION
'At this point forward, we should only have REAL numbers to process
IF Exponent
> 1 THEN NumErr$
= NumErr$
+ "Multiple E/D exponent characters in string. ":
EXIT FUNCTION
IF minus
THEN NumErr$
= NumErr$
+ "Multiple negative signs (-) encountered. ":
EXIT FUNCTION IF plus
THEN NumErr$
= NumErr$
+ "Multiple negative signs (-) encountered. ":
EXIT FUNCTION IF minus
> 1 THEN NumErr$
= NumErr$
+ "Multiple negative signs (-) encountered. ":
EXIT FUNCTION IF plus
> 1 THEN NumErr$
= NumErr$
+ "Multiple negative signs (-) encountered. ":
EXIT FUNCTION
IF period
> 1 THEN NumErr$
= NumErr$
+ "Multiple decimal points (.) encountered. ":
EXIT FUNCTION
IF p
> e
THEN NumErr$
= NumErr$
+ "Decimal points (.) AFTER E/D exponent encountered. ":
EXIT FUNCTION
CASE "0" TO "9", "-", "+", ".", "D", "E" 'we should have validated all these characters earlier NumErr$
= NumErr$
+ "Invalid Character (" + t$
+ ") encountered. ":
EXIT FUNCTION
'We should've passed all the error checking by this point -- I think...
evaluateintegers:
'first compare for all types
IF t##
= -1 OR t##
= 0 THEN NumType
= NumType
OR 32 'signed bit IF t##
>= -128 AND t##
<= 127 THEN NumType
= NumType
OR 64 'signed byte IF t##
>= -32768 AND t##
<= 32767 THEN NumType
= NumType
OR 128 'signed integer IF t##
>= -2147483648 AND t##
<= 2147483647 THEN NumType
= NumType
OR 256 'signed long IF t##
>= -9223372036854775808 AND t##
<= 9223372036854775807 THEN NumType
= NumType
OR 512 'signed integer64 NumType
= NumType
OR 16384 'signed offset IF t##
= 1 OR t##
= 0 THEN NumType
= NumType
OR 1 'unsigned bit IF t##
>= 0 AND t##
<= 255 THEN NumType
= NumType
OR 2 'unsigned byte IF t##
>= 0 AND t##
<= 65535 THEN NumType
= NumType
OR 4 'unsigned integer IF t##
>= 0 AND t##
<= 4294967295 THEN NumType
= NumType
OR 8 'unsigned long IF t##
>= 0 AND t##
<= 18446744073709551615 THEN NumType
= NumType
OR 16 'unsigned integer64 NumType
= NumType
OR 8192 'unsigned offset
IF t##
>= -2.802597D45
AND t##
<= 3.402823D
+38 THEN NumType
= NumType
OR 1024 'single IF t##
>= -4.490656458412465E324 AND t##
<= 1.797693134862310E+308 THEN NumType
= NumType
OR 2048 'double IF t##
>= -1.18E4932 AND t##
<= 1.18E+4932 THEN NumType
= NumType
OR 4096 'float
IF r
THEN 'we have specific suffix; only decide if the value is valid for it NumType = 0
IF t##
= -1 OR t##
= 0 THEN NumType
= 32 'signed bit IF t##
>= -128 AND t##
<= 127 THEN NumType
= 64 'signed byte IF t##
>= -32768 AND t##
<= 32767 THEN NumType
= 128 'signed integer IF t##
>= -2147483648 AND t##
<= 2147483647 THEN NumType
= 256 'signed long IF t##
>= -9223372036854775808 AND t##
<= 9223372036854775807 THEN NumType = 512 'signed integer64
NumType = 16384 'signed offset
IF t##
>= -2.802597E-45 AND t##
<= 3.402823E+38 THEN NumType
= 1024 'single IF t##
>= -4.490656458412465E-324 AND t##
<= 1.797693134862310E+308 THEN NumType
= 2048 'double IF t##
>= -1.18E-4932 AND t##
<= 1.18E+4932 THEN NumType
= 4096 'float IF t##
= 0 OR t##
= 1 THEN NumType
= 1 'unsigned bit IF t##
>= 0 AND t##
<= 255 THEN NumType
= 2 'unsigned byte IF t##
>= 0 AND t##
<= 65535 THEN NumType
= 4 'unsigned integer IF t##
>= 0 AND t##
<= 4294967295 THEN NumType
= 8 'unsigned long IF t##
>= 0 AND t##
<= 18446744073709551615 THEN NumType = 16 'unsigned integer64
NumType = 8192 'unsigned offset
IF NumType
= 0 THEN NumErr$
= "Invalid Suffix. "
Never one to shy from a challenge, and being one who loves to over-engineer a simple project, I bring you the glorious FUNCTION NumType!
Pass it a string and watch as it not only decides IF it's a number for you, but what TYPE of number you gave it! It detects bits, bytes, integers, singles, floats, offsets... Signed and unsigned!
It works with &H, &B, &O values.
You can set your string a suffix like 123&& and see if it's a valid _INTEGER64...
It generates error messages, so you can see WHY it's not a number!
It's my over-engineered "Is it a number" Function....
Test it out, and let me know if it generates false positives for anything.
One important note:
A value such as 1E3 *will* be listed as a valid INTEGER. In the end, it's nothing more than 1,000 -- and that's a perfectly fine integer. Just because you WRITE an integer in scientific notation, doesn't mean it stops being an integer...
&HFF is an integer. (255)
2.55E2 is also the same integer. (255)
Don't think it's a glitch -- it's actually working as intended (to my way of thinking), in these instances. If 1E2
isn't an integer, then why is &H10??