|
|
| Author |
Message |
stevech
Joined: 23 Feb 2006
Posts: 657
|
|
Posted: 22 October 2006, 2:46 AM Post subject: valueS bug? |
|
|
A bug, I think, where valueS does not always stop parsing at whitespace or has to do with odd/even number of chars. Seems to me that both cases, below, should succeed in parsing the value -8.
| Code: | s="-8 123"
s=mid(s,1,5)
call valueS(s, v, ok)
debug.print s;" valueS=";cstr(v);" ";cstr(ok)
s="-8 123"
s=mid(s,1,4)
call valueS(s, v, ok)
debug.print s;" valueS=";cstr(v);" ";cstr(ok)
|
output is
-8 12 valueS=0.0 False
-8 1 valueS=-8.0 True
variables: s is string; v is single, ok is boolean |
|
| Back to top |
|
 |
dkinzer Site Admin
Joined: 03 Sep 2005
Posts: 2499
Location: Portland, OR
|
|
Posted: 22 October 2006, 3:30 AM Post subject: Re: valueS bug? |
|
|
| stevech wrote: | | Seems to me that both cases, below, should succeed in parsing the value -8. |
Actually, both cases should fail. The passed string must be a valid floating point number and may optionally have leading and/or trailing whitespace.
The discrepancy that you identified has been confirmed. The code incorrectly accepts one arbitrary character following the trailing whitespace. A solution has been identified but still needs to be regression tested. |
|
| Back to top |
|
 |
stevech
Joined: 23 Feb 2006
Posts: 657
|
|
Posted: 22 October 2006, 4:25 AM Post subject: |
|
|
I'd vote that valueS would ignore all stuff after the number - i.e., the space and all chars to the right. Doing so makes parsing a string with multiple numbers in it easier.
I don't think the writeup for valueS says what the behavior is for 2+ numbers in the string, so it could just ignore the second. Spaces aren't allowed in scientific notation, right? such as
10 E6
10e -7
are illegal |
|
| Back to top |
|
 |
dkinzer Site Admin
Joined: 03 Sep 2005
Posts: 2499
Location: Portland, OR
|
|
Posted: 22 October 2006, 5:22 AM Post subject: |
|
|
| stevech wrote: | | I'd vote that valueS would ignore all stuff after the number - i.e., the space and all chars to the right. Doing so makes parsing a string with multiple numbers in it easier. |
Perhaps, but that would break existing code and it is inconsistent with the behavior of ValueS() as implemented in BasicX. |
|
| Back to top |
|
 |
dkinzer Site Admin
Joined: 03 Sep 2005
Posts: 2499
Location: Portland, OR
|
|
Posted: 22 October 2006, 20:39 PM Post subject: |
|
|
Here is a function that might be useful to extract one or more whitespace separated Single values from a string. It could be easily modified to allow other separator characters.
| Code: | '
'' GetValSingle
'
' Attempt to extract a Single value from a string beginning at the
' given 1-based index. Leading whitespace characters are skipped
' and then a conversion is attempted on the longest sequence of non-
' whitespace characters.
'
' If the conversion is successful, the resulting value is returned
' directly, the valOK flag is set true and passed index is updated
' to lie just beyond the last character converted.
'
' If the conversion fails, the returned value is 0.0, the valOK flag
' is set false and the passed index is updated to be the index of
' the first character of the sequence on which conversion was attempted
' (i.e., leading whitespace is skipped).
'
Function GetValSingle(ByVal str as String, ByRef idx as Integer, ByRef valOK as Boolean) as Single
GetValSingle = 0.0
valOK = False
' determine the length of the string
Dim slen as Integer
slen = Len(str)
If ((idx > 0) And (idx <= slen)) Then
' skip over leading whitespace characters
Dim c as Byte
Do While (idx <= slen)
c = Asc(str, idx)
If ((c <> Asc(" ")) And (c <> &H09)) Then
Exit Do
End If
idx = idx + 1
Loop
' determine the number of non-whitespace characters
Dim convLen As Integer
convLen = 0
Do While ((idx + convLen) <= slen)
c = Asc(str, idx + convLen)
If ((c = Asc(" ")) Or (c = &H09)) Then
Exit Do
End If
convLen = convLen + 1
Loop
' attempt conversion if characters are available
If (convLen > 0) Then
Dim s as String
s = Mid(str, idx, convLen)
Call ValueS(s, GetValSingle, valOK)
If (valOK) Then
idx = idx + convLen
End If
End If
End If
End Function |
Here is a small test stub that shows how it can be used:
| Code: | Sub Main()
Dim s as String
Dim idx as Integer
Dim slen as Integer
s = " 123 4.5e4 1.0 "
slen = Len(s)
idx = 1
Do While (idx <= slen)
Dim ok as Boolean
Dim f as Single
f = GetValSingle(s, idx, ok)
If (ok) Then
Debug.Print "val = "; Fmt(f, 3); ", idx = "; CStr(idx)
ElseIf (idx > slen) Then
Debug.Print "-- end of string --"
Else
Debug.Print "invalid characters at ["; Mid(s, idx); "]"
Exit Do
End If
Loop
End Sub
|
|
|
| Back to top |
|
 |
stevech
Joined: 23 Feb 2006
Posts: 657
|
|
Posted: 22 October 2006, 21:13 PM Post subject: |
|
|
thanks Don
Would be nice to organize some sort of library of goodies here on the forum - searchable.
use of DIMs in middle of function or sub - - I've never gotten in the habit of doing that. I see it done in C/C++ frequently. Perhaps it has advantages in maintaing code with the DIMs nearest the code that uses that var. |
|
| Back to top |
|
 |
dkinzer Site Admin
Joined: 03 Sep 2005
Posts: 2499
Location: Portland, OR
|
|
Posted: 22 October 2006, 23:59 PM Post subject: |
|
|
| stevech wrote: | | use of DIMs in middle of function or sub - - I've never gotten in the habit of doing that. I see it done in C/C++ frequently. Perhaps it has advantages in maintaining code with the DIMs nearest the code that uses that var. |
I got in the habit of doing that when I began using C++ a number of years ago. It seems more logical to define the variables near where they are first used rather than at the top of the procedure as must be done in C.
In ZBasic, it doesn't affect the efficiency of the code at all. You're free to define variables anywhere you wish as long as they are defined before their first use.
There is a slight efficiency advantage to defining variables in a block when they are only used within the block. The compiler reuses the stack space for variables defined in subsequent blocks.
Last edited by dkinzer on 23 October 2006, 18:53 PM; edited 1 time in total |
|
| Back to top |
|
 |
stevech
Joined: 23 Feb 2006
Posts: 657
|
|
Posted: 23 October 2006, 0:35 AM Post subject: |
|
|
| One consideration on microprocessors - having all the local variables in one block helps get an overview of whether or not the sub/function is using a lot of stack space and might need tightening-up. On a Gigabyte PC, this doesn't matter much. |
|
| Back to top |
|
 |
dkinzer Site Admin
Joined: 03 Sep 2005
Posts: 2499
Location: Portland, OR
|
|
Posted: 23 October 2006, 1:09 AM Post subject: |
|
|
| For finding the stack-hungry routines the .map file is helpful as well. The section titled "--- Procedures" lists each routine and its stack requirement. |
|
| Back to top |
|
 |
|