PlanetSquires Forums

Support Forums => Other Software and Code => Topic started by: raymw on January 30, 2017, 02:47:28 PM

Title: Is_number
Post by: raymw on January 30, 2017, 02:47:28 PM
Today's question.

Freebasic has an IsDate function, but nothing for IsNumber, afaik. It is quite possible for a user to enter a number with more than one decimal point or alphabetic characters in a field, and conversions, such as Val(astring) will result in a valid number, up to the first error character.

Some systems I have used prevent the entry of any characters which are not numbers, others insist on deleting the existing entry before entering the new, other send warning beeps, etc.

I'm not sure if there is recommended parsing strategy in freebasic, but what I've done is convert the string to a number, then convert said number back to a string and compare with original string. I had to do a bit of extra stripping of zeros from leading and trailing part of original string, check for more than one decimal point, and adjust the string so that that decimal numbers began with '0.nnnn' cf '.nnnn' and ended as 'nnnn' cf 'nnnn.' I am not interested in '+' or '-', entry as those will be treated as non numeric, but that can be easily altered.

So, is there a more succinct method of validating numeric entries?
Title: Re: Is_number
Post by: Paul Squires on January 30, 2017, 04:41:09 PM
I think this is maybe what you are looking for?

http://www.planetsquires.com/protect/forum/index.php?topic=2916.msg21686#msg21686

I wrote in PB but it should be very easy to convert to FB.
Title: Re: Is_number
Post by: raymw on January 30, 2017, 06:58:15 PM
thanks. I had thought of testing each character of the string, but hadn't cottoned on with the select/case method, being stuck with thinking of instr. It probably won't make much difference to my simple program, but I may substitute a version of what you have suggested for my solution, just for the sake of trying it out.
Title: Re: Is_number
Post by: raymw on January 31, 2017, 12:35:42 PM
for the sake of completeness, here is my original code, which works fine for what I want. I call it as the textbox is read, and if it is not a valid number, I change the background colour of the textbox. Basically it compares the way in which fb converts a number to a text string, compared to how the text is originally entered by the user. It could be fine tuned to be consistent with + and - (+ is assumed in converting a value to a string - if the user enters '+' it is shown as an error)  Also, for my particular application, a data entry value of zero is not allowed. Function isnotanumber(a as String) as boolean   ' checks if valid decimal number.
                                               'returns false if  a number
             
              Dim r as String        ' result string
              Dim dpc as Integer = 0 ' decimal point count   
                     
             If (Val(a) =0.0) Then  Return True         'not allow zero   
                       a=  LTrim (RTrim (a,"0"),"0")         'remove leading/trailing 0's     
                                             
                        r=Str(Val(a))   'get string from value a
                                 
                                dpc=InStr(1,a,".")              'check for only 1 dp
                                   If dpc<>0 Then 
                                     dpc=InStr(dpc+1, a,".")
                                        If dpc<>0 Then
                                            Return True          'return true for more dp's
                                        End If   
                                   End If 
                                                   'correct for leading and trailing decimal point
                        If (Left(a,1) =".") Then a="0"+a     'put 0 in front of dp
                        If (Right(a,1) =".") Then a = Left (a, Len(a)-1)  'remove dp if last char
                        If (r<> a) Then Return True
                       
                     
                Return False
End Function
Title: Re: Is_number
Post by: Paul Squires on January 31, 2017, 04:21:17 PM
Certainly many ways that you can accomplish it. Whichever way works and is easy to read and understand certainly is the way to go.

For the fun of it, I modified your code ever so slightly while still preserving the overall intent and logic of your code. Notice my use of TRIM, LTRIM and RTRIM using the second parameter to remove characters other than a space. Also, look at how I searched the string for multiple period characters. In FB, you can traverse a string using array indexing directly without first having to create a byte pointer. Pretty cool and useful.


Function isnotanumber(ByRef a As String) As boolean   ' checks if valid decimal number.
                                                      ' returns false if a number
             
  Dim r As String        ' result string
  Dim dpc As Integer = 0 ' decimal point count   
         
  If Val(a) = 0 Then Return True         'not allow zero   

  a = Trim(a, "0")    'remove leading/trailing 0's     
  r = Str(Val(a))     'get string from value a
           
  For i As Long = 0 To Len(a) - 1
     If a[i] = 46 Then dpc += 1   ' look for periods (ascii(46))
     If dpc > 1 Then Return True
  Next

  ' correct for leading and trailing decimal point
  If Left(a, 1) = "." Then a = "0" + a      'put 0 in front of dp
  If Right(a,1) = "." Then a = Rtrim(a, ".")  ' remove ending decimal
 
  If r <> a Then Return True
       
  Return False
End Function

Print isnotanumber("0")
Print isnotanumber("03as.3")
Print isnotanumber("0.44.5")
Print isnotanumber("99.345")