One more IsNumber()

Share your advanced PureBasic knowledge/code with the community.
said
Enthusiast
Enthusiast
Posts: 342
Joined: Thu Apr 14, 2011 6:07 pm

One more IsNumber()

Post by said »

Hi,

Here is one more IsNumber() procedure :)
Should accept all known numeric formats (i hope it is bug free, though not 100% sure as always :? ) despite all the tests as you can see below, so please if you find any bug, let me know, thanks :D

Code: Select all

EnableExplicit

Procedure   My_IsNumber(txt.s)
    ; sign +/- : is accepted at the begining or after e (begining <=> prv = 0)
    ; dot   .  : is accepted anywhere but once only
    ; exp   e  : is validated if preceeded by a digit and ( followed by a digit or followed by a sign digit)
    ; A valid number will have its ValD() correct
    ;
    Protected   cur.c, prv.c, *p.Character, i, n, nbr_dot, nbr_exp, vld_exp, nbr_dgt
    n = Len(txt)
    If n = 0 : ProcedureReturn #False : EndIf
    For i=1 To n
        prv = cur
        *p  = @txt + (i-1) * SizeOf(Character)
        cur = *p\c
        
        Select cur
            Case '+', '-'
                If (prv <> 'e') And (prv <> 0) : ProcedureReturn #False : EndIf
                
            Case '.'
                nbr_dot + 1
                If nbr_exp > 0  : ProcedureReturn #False : EndIf
                
            Case 'e'
                If (prv = '.') Or ((prv >= '0') And (prv <= '9'))
                    nbr_exp + 1
                    vld_exp = -1                        ; an 'e' has started
                Else
                    ProcedureReturn #False
                EndIf
                
            Case '0' To '9'
                If vld_exp = -1 : vld_exp + 1 : EndIf   ; closing started 'e' if any
                nbr_dgt + 1
            Default
                ProcedureReturn #False
        EndSelect
        If (nbr_dot > 1) Or (nbr_exp > 1) : ProcedureReturn #False : EndIf
    Next
    
    If vld_exp <> 0 : ProcedureReturn #False : EndIf
    If nbr_dgt <= 0 : ProcedureReturn #False : EndIf
    ProcedureReturn #True
    
EndProcedure
Procedure Test_IsNumber(txt.s)
    If My_IsNumber(txt)
        Debug "[" + txt + "] ..... is a Valid Number     .... ValD = " + StrD(ValD(txt))
    Else
        Debug "[" + txt + "] ..... is NOT a Valid Number .... ValD = " + StrD(ValD(txt))
    EndIf
EndProcedure

Debug "--------- No Valid Number ------------"
Test_IsNumber("")
Test_IsNumber("a")
Test_IsNumber("+")
Test_IsNumber("123a")
Test_IsNumber("a123")
Test_IsNumber("e4")
Test_IsNumber("4e")
Test_IsNumber("4ee1")
Test_IsNumber("++41")
Test_IsNumber("--41")
Test_IsNumber("+4+")
Test_IsNumber("+4-")
Test_IsNumber("-4+")
Test_IsNumber("-4e")
Test_IsNumber("+4e")
Test_IsNumber("4e.3")
Test_IsNumber("4e.-3")
; ----
Debug "--------- Valid Number ------------"
Test_IsNumber("0")
Test_IsNumber("123")
Test_IsNumber("12.3")
Test_IsNumber("0.0123")
Test_IsNumber(".123")
Test_IsNumber("4e0")
Test_IsNumber("4e2")
Test_IsNumber("2.1e1")
Test_IsNumber("2.1e-1")
Test_IsNumber("2.1e+1")
Test_IsNumber("0.1e1")
Test_IsNumber("0.1e0")
Test_IsNumber("0.1e-1")
Test_IsNumber("0.1e+1")
Test_IsNumber("0.1e0")
Test_IsNumber(".1e1")
Test_IsNumber(".1e-1")
Test_IsNumber(".1e+1")
Test_IsNumber(".1e0")

Test_IsNumber("+0")
Test_IsNumber("+123")
Test_IsNumber("+12.3")
Test_IsNumber("+0.0123")
Test_IsNumber("+.123")
Test_IsNumber("+4e0")
Test_IsNumber("+4e2")
Test_IsNumber("+2.1e1")
Test_IsNumber("+2.1e-1")
Test_IsNumber("+2.1e+1")
Test_IsNumber("+0.1e1")
Test_IsNumber("+0.1e0")
Test_IsNumber("+0.1e-1")
Test_IsNumber("+0.1e+1")
Test_IsNumber("+0.1e0")
Test_IsNumber("+.1e1")
Test_IsNumber("+.1e-1")
Test_IsNumber("+.1e+1")
Test_IsNumber("+.1e0")

Test_IsNumber("-0")
Test_IsNumber("-123")
Test_IsNumber("-12.3")
Test_IsNumber("-0.0123")
Test_IsNumber("-.123")
Test_IsNumber("-4e0")
Test_IsNumber("-4e2")
Test_IsNumber("-2.1e1")
Test_IsNumber("-2.1e-1")
Test_IsNumber("-2.1e+1")
Test_IsNumber("-0.1e1")
Test_IsNumber("-0.1e0")
Test_IsNumber("-0.1e-1")
Test_IsNumber("-0.1e+1")
Test_IsNumber("-0.1e0")
Test_IsNumber("-.1e1")
Test_IsNumber("-.1e-1")
Test_IsNumber("-.1e+1")
Test_IsNumber("-.1e0")


User avatar
skywalk
Addict
Addict
Posts: 4219
Joined: Wed Dec 23, 2009 10:14 pm
Location: Boston, MA

Re: One more IsNumber()

Post by skywalk »

The nice thing about standards is there are so many to choose from. ~ Andrew Tanenbaum
Post Reply