|
|
| Author |
Message |
mwf
Joined: 06 Oct 2006
Posts: 27
Location: Boulder, CO
|
|
Posted: 06 October 2006, 18:22 PM Post subject: String to Ulong |
|
|
| Is there an elegent way to convert a string to unsigned long when the number is too big to fit in a Single? I can't loose the low bits. |
|
| Back to top |
|
 |
dkinzer Site Admin
Joined: 03 Sep 2005
Posts: 2499
Location: Portland, OR
|
|
Posted: 06 October 2006, 19:32 PM Post subject: Re: String to Ulong |
|
|
| mwf wrote: | | Is there an elegent way to convert a string to unsigned long when the number is too big to fit in a Single? |
Elegant or not, here is a function that does the job. It also detects overflow and the presence of invalid characters. You can use Trim() to remove leading and trailing spaces before calling it.
You can remove the errFlag parameter if it is not needed. The routine can be easily modified to handle Byte and Unsigned values. It could also be modified to handle signed values with a little more work.
| Code: | '
'' StrVal
'
' Convert a string to a numeric value. If any characters in the string
' are non-digits or if the string has zero length, an error indication
' is returned indirectly through the 'errFlag' variable. Also, if the
' value is too large to be represented as an UnsignedLong an error
' indication is returned.
'
' If 'errFlag' is set True, the value returned is undefined.
'
Private Const ULONG_LIMIT as UnsignedLong = &HFFFFFFFF \ 10
Private Const LAST_DIGIT as Byte = &HFFFFFFFF Mod 10
Function StrValUL(ByVal s as String, ByRef errFlag as Boolean) as UnsignedLong
Dim cnt as Integer
Dim digitCnt as Byte
Dim idx as Integer
Dim digitVal as Byte
' initialize tracking variables
StrVal = 0
digitCnt = 0
errFlag = False
cnt = Len(s)
For idx = 1 to cnt
' convert the character to a digit, check validity
digitVal = Asc(s, idx) - Asc("0")
If (digitVal > 9) Then
errFlag = True
Exit For
ElseIf ((digitCnt > 0) Or (digitVal > 0)) Then
' check for overflow
If ((StrVal > ULONG_LIMIT) Or ((StrVal = ULONG_LIMIT) And (digitVal > LAST_DIGIT))) Then
' this digit will cause overflow
errFlag = True
Exit For
End If
' add in another digit
StrVal = (StrVal * 10) + CULng(digitVal)
digitCnt = digitCnt + 1
End If
Next idx
If (cnt = 0) Then
errFlag = True
End If
End Function
|
[Edit: added the check for an empty string.]
Last edited by dkinzer on 06 October 2006, 23:03 PM; edited 1 time in total |
|
| Back to top |
|
 |
mwf
Joined: 06 Oct 2006
Posts: 27
Location: Boulder, CO
|
|
Posted: 06 October 2006, 22:42 PM Post subject: |
|
|
| Thanks. The overflow check is much cleaner than where I was going. |
|
| Back to top |
|
 |
dkinzer Site Admin
Joined: 03 Sep 2005
Posts: 2499
Location: Portland, OR
|
|
Posted: 06 October 2006, 22:55 PM Post subject: |
|
|
| mwf wrote: | | The overflow check is much cleaner than where I was going. |
Checking for overflow is complicated by the fact that there is no data type larger than the type being generated. It could be done by using two UnsignedLong values and implementing a 64-bit multiply-and-add function. The method used is probably simpler, though perhaps a bit obtuse, and still yields the full range of values. As you most likely already figured out, the check is implemented by determining if adding in the next digit would cause overflow rather than attempting to do detect it after the fact. |
|
| Back to top |
|
 |
dkinzer Site Admin
Joined: 03 Sep 2005
Posts: 2499
Location: Portland, OR
|
|
Posted: 06 October 2006, 23:01 PM Post subject: |
|
|
I just realized that the test for an empty string got eliminated somewhere along the line. That can be fixed by adding the following code just before the end of the function:
| Code: | If (cnt = 0) Then
errFlag = True
End If |
|
|
| Back to top |
|
 |
|