|
-
Jan 10th, 2007, 12:00 PM
#1
Thread Starter
Hyperactive Member
Handling Unsigned Long (Resolved)
Hi guys,
I'm sure this is easy for you lot, but I'm having trouble finding a solution.
I have a CRC32 calculation I wrote in C and am now porting it to VB, but storing the values as Long or Currency doesn't seem to help. When I use long values it treats the value as signed which messes things up in the divide etc, and when I use Currency I get overflow errors.
The calc is below:
Code:
Function crc(a As Long, b As Long) as long
Dim p1, p2 As Long
p1 = ((a) Xor (b))
p1 = p1 And &HFF
p2 = ((a) / 256)
crc = CrcTable(p1) Xor p2
End Function
CRCTable is an array of Unsigned Long values which I've inserted as &H values.
I'd appreciate any help with this, as I'm sure there must be a work around.
Thanks
Last edited by LucaUWF; Jan 12th, 2007 at 06:48 AM.
Reason: Resolved
-
Jan 10th, 2007, 12:02 PM
#2
Re: Handling Unsigned Long
One problem is that p1 is not declared as Long or Currency - it is declared as Variant. You need to specify the type for each variable, eg:
VB Code:
Dim p1 As Long, p2 As Long
-
Jan 10th, 2007, 12:03 PM
#3
Re: Handling Unsigned Long
Using thisProduces one Variant and one Long where I think you want two Longs. Try this
VB Code:
Dim p1 As Long, p2 As Long
-
Jan 10th, 2007, 12:08 PM
#4
Thread Starter
Hyperactive Member
Re: Handling Unsigned Long

Ah, thanks guys, that's helped with the first part of the function... but the next problem is the divide, it divides with a negative number and returns 0.
E.g. call the function with:
a = &HFFFFFFFF
b = 83
How can I avoid this?
-
Jan 10th, 2007, 12:19 PM
#5
Re: Handling Unsigned Long
The problem is that "a" has a value of -1.. I can't remember how to work around that (using & etc after the value doesnt work).
I think there is something in the CodeBank about using Unsigned Longs, or 'extra large' numbers.. I'll have a search for it later.
-
Jan 10th, 2007, 12:23 PM
#6
Thread Starter
Hyperactive Member
Re: Handling Unsigned Long
Thanks si,
I'll have a little look myself now, but unfortunately I'm travelling in 10mins.
Thanks
-
Jan 10th, 2007, 01:33 PM
#7
Re: Handling Unsigned Long
These functions allow you to do Unsigned Long to Currency conversion:
VB Code:
Public Function CurToLong(ByVal Value As Currency) As Long
If Value > &H7FFFFFF Then
CurToLong = &H80000000 Or CLng(Value - 2147483648#)
Else
CurToLong = CLng(Value)
End If
End Function
Public Function LongToCur(ByVal Value As Long) As Currency
If Value < 0 Then
LongToCur = CCur(Value And &H7FFFFFFF) + 2147483648#
Else
LongToCur = CCur(Value)
End If
End Function
Now the important part you have to deal with is what actually happens with binary values when you handle something. The most important thing is to work with the correct datatypes. One of the biggest problems is that logical operators only work with real integer datatypes: Long, Integer, Byte, Boolean (Boolean is a hacked Integer with value of 0 or -1 or &H7FFFF). Mod and \ operators only work with integer datatypes as well.
VB fits given hexadecimal values (or any value for that matter) to the smallest possible datatype. &HFFFF fits in an Integer, so it is an Integer, being equal to -32768. If you wanted to use it with Long and being a positive value, you'd have to give & to force it to a Long, thus &HFFFF& gives you 65535. This is part of VB's way of coercing datatypes.
Of course, we hit a wall with Long: VB doesn't let you write bigger hexadecimal values than what a Long can hold. So you have only arithmetic operators, multiplying and dividing and some others that you can use.
So... as long as you can keep track of what happens on bit level you should be ok when you do something. Hopefully this post helps enough on achieving that goal
-
Jan 11th, 2007, 12:19 AM
#8
Re: Handling Unsigned Long
Here is the CRC function rewritten:
VB Code:
Function CRC(ByVal A As Long, ByVal B As Long) As Long
If A >= 0 Then
CRC = CRCtable((A Xor B) And &HFF&) Xor (A \ &H100&)
Else
CRC = CRCtable((A Xor B) And &HFF&) Xor (((A And &H7FFFFF00) \ &H100&) Or &H800000)
End If
End Function
Now, first we check if A is negative or not. If it is negative, then we have to ignore to highest bit to disable problems with the signed datatype, then do the math and include was-the-highest-bit back in. Other than that the processing is similar in both cases.
The ignoring of highest bit is done using &H7FFFFFFF and then the bit is put back into the correct place with &H800000 after the bitshift is done. Note that if you're at some point aiming for speed in VB6, you would be better of writing as much code inline as possible instead of writing helper functions. Of course at the moment the most important thing is to get the whole thing working 
Oh, and handling numeric datatypes is faster via ByVal than ByRef. (ByVal passes value of given variable to a new local variable, ByRef passes pointer to the existing variable.)
-
Jan 11th, 2007, 05:31 AM
#9
Thread Starter
Hyperactive Member
Re: Handling Unsigned Long
Thanks Merri that's great and makes a lot of sense. 
I'll try this out later when I get the chance.
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|