|
code
newsgroups
|
|||||||||||||||||||||||
|
|||||||||||||||||||||||
Decimal to LongsNeed to convert a Decimal(Variant) to two longs.
Dim vNbr as Variant Dim vNbr1 as Variant Dim vNbr2 as Variant vNbr = CDec(0) vNbr1 = CDec(123456) ' e.g. vNbr2 = CDec(987654) vNbr = vNbr1 * vNbr2 ' Now I need the Decimal Variant broken into two Longs. The Sub might look like, returninh lHi and lLo Public Sub Convert(vNbr as Variant, lHo as Long, lLo as long) ... End Sub
Show quote
Hide quote
"Lorin" <Lo***@discussions.microsoft.com> wrote in message You mean split a Long into its hi and low words?news:D2ABCAB3-1A5E-473E-998E-AF9B47CB86B2@microsoft.com... > Need to convert a Decimal(Variant) to two longs. > Dim vNbr as Variant > Dim vNbr1 as Variant > Dim vNbr2 as Variant > > vNbr = CDec(0) > vNbr1 = CDec(123456) ' e.g. > vNbr2 = CDec(987654) > vNbr = vNbr1 * vNbr2 > > ' Now I need the Decimal Variant broken into two Longs. > The Sub might look like, returninh lHi and lLo > Public Sub Convert(vNbr as Variant, lHo as Long, lLo as long) If so, try this: Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (Destination As Any, Source As Any, ByVal Length As Long) Public Function GetHiLoWord(ByVal DWord As Long, ByRef LoWord As Long, ByRef HiWord As Long) As Boolean LoWord = GetLoWord(DWord) HiWord = GetHiWord(DWord) GetHiLoWord = True End Function Public Function GetLoWord(DWord As Long) As Integer ' 'GetLoWord = dWord And &HFFFF& ' If dWord And &H8000& Then ' GetLoWord = dWord Or &HFFFF0000 ' Else ' GetLoWord = dWord And &HFFFF& ' End If CopyMemory GetLoWord, DWord, 2 End Function Public Function GetHiWord(ByVal DWord As Long) As Integer GetHiWord = (DWord And &HFFFF0000) \ 65536 End Function If not, I have no idea what you're asking. -- Mike Microsoft Visual Basic MVP
Show quote
Hide quote
> Need to convert a Decimal(Variant) to two longs. You are aware that the Decimal data type can hold numbers bigger than two > Dim vNbr as Variant > Dim vNbr1 as Variant > Dim vNbr2 as Variant > > vNbr = CDec(0) > vNbr1 = CDec(123456) ' e.g. > vNbr2 = CDec(987654) > vNbr = vNbr1 * vNbr2 > > ' Now I need the Decimal Variant broken into two Longs. > The Sub might look like, returninh lHi and lLo > Public Sub Convert(vNbr as Variant, lHo as Long, lLo as long) > ... > End Sub Longs can hold, right? Is there a maximum value you will be dealing with? Also, did you have a split value number in mind or are you willing to use 2147483647 which is the largest Long value? Rick
Show quote
Hide quote
"Lorin" <Lo***@discussions.microsoft.com> wrote in message As Rick has already said, are you aware that the byte size of a Decimal is news:D2ABCAB3-1A5E-473E-998E-AF9B47CB86B2@microsoft.com... > Need to convert a Decimal(Variant) to two longs. > Dim vNbr as Variant > Dim vNbr1 as Variant > Dim vNbr2 as Variant > > vNbr = CDec(0) > vNbr1 = CDec(123456) ' e.g. > vNbr2 = CDec(987654) > vNbr = vNbr1 * vNbr2 > ' Now I need the Decimal Variant broken into two Longs. > The Sub might look like, returninh lHi and lLo more than the byte size of two Longs? In fact a Decimal uses 14 bytes and is essentially a large integer scaled by a variable power of 10. If, as I suspect, you want a variable that uses 8 bytes of data then perhaps you could have a look at the Currency data type, which has the advantage that it does not need to be contained in a Variant. Mike
Show quote
Hide quote
"Lorin" wrote: The Decimal(variant) will never be greater that what two longs can hold.> Need to convert a Decimal(Variant) to two longs. > Dim vNbr as Variant > Dim vNbr1 as Variant > Dim vNbr2 as Variant > > vNbr = CDec(0) > vNbr1 = CDec(123456) ' e.g. > vNbr2 = CDec(987654) > vNbr = vNbr1 * vNbr2 > > ' Now I need the Decimal Variant broken into two Longs. > The Sub might look like, returninh lHi and lLo > Public Sub Convert(vNbr as Variant, lHo as Long, lLo as long) > ... > End Sub > To make it clearer ... I will be incrementing the Decimal and using the result to set the pointer for a file operation. e.g. a DVD .iso file. The file can be much longer than 2G so this is the need to handle larger than one long. The syntax is lRet = SetFilePointer(m_hFile, lOffsetLo, lOffsetHi, FILE_CURRENT)
Show quote
Hide quote
>> Need to convert a Decimal(Variant) to two longs. Does this subroutine do what you want?>> Dim vNbr as Variant >> Dim vNbr1 as Variant >> Dim vNbr2 as Variant >> >> vNbr = CDec(0) >> vNbr1 = CDec(123456) ' e.g. >> vNbr2 = CDec(987654) >> vNbr = vNbr1 * vNbr2 >> >> ' Now I need the Decimal Variant broken into two Longs. >> The Sub might look like, returninh lHi and lLo >> Public Sub Convert(vNbr as Variant, lHo as Long, lLo as long) >> ... >> End Sub >> > > The Decimal(variant) will never be greater that what two longs can hold. > To make it clearer ... > I will be incrementing the Decimal and using the result to set the pointer > for a file operation. e.g. a DVD .iso file. > The file can be much longer than 2G so this is the need to handle larger > than one long. Public Sub Convert(vNbr As Variant, lHigh As Long, lLow As Long) Dim MaxLong As Variant Dim TempHigh As Variant Dim TempLow As Variant MaxLong = CDec(CDec(2 ^ 31) - 1) TempHigh = CDec(Int(CDec(vNbr) / MaxLong)) TempLow = vNbr - TempHigh * MaxLong If TempLow = 0 Then lHigh = CLng(TempHigh - 1) lLow = CLng(MaxLong) Else lHigh = CLng(TempHigh) lLow = CLng(TempLow) End If End Sub Rick I think there is a one off problem here as we turn the corner at max long.
Also, what happens to INT() with Large numbers? Show quoteHide quote "Rick Rothstein (MVP - VB)" wrote: > >> Need to convert a Decimal(Variant) to two longs. > >> Dim vNbr as Variant > >> Dim vNbr1 as Variant > >> Dim vNbr2 as Variant > >> > >> vNbr = CDec(0) > >> vNbr1 = CDec(123456) ' e.g. > >> vNbr2 = CDec(987654) > >> vNbr = vNbr1 * vNbr2 > >> > >> ' Now I need the Decimal Variant broken into two Longs. > >> The Sub might look like, returninh lHi and lLo > >> Public Sub Convert(vNbr as Variant, lHo as Long, lLo as long) > >> ... > >> End Sub > >> > > > > The Decimal(variant) will never be greater that what two longs can hold. > > To make it clearer ... > > I will be incrementing the Decimal and using the result to set the pointer > > for a file operation. e.g. a DVD .iso file. > > The file can be much longer than 2G so this is the need to handle larger > > than one long. > > Does this subroutine do what you want? > > Public Sub Convert(vNbr As Variant, lHigh As Long, lLow As Long) > Dim MaxLong As Variant > Dim TempHigh As Variant > Dim TempLow As Variant > MaxLong = CDec(CDec(2 ^ 31) - 1) > TempHigh = CDec(Int(CDec(vNbr) / MaxLong)) > TempLow = vNbr - TempHigh * MaxLong > If TempLow = 0 Then > lHigh = CLng(TempHigh - 1) > lLow = CLng(MaxLong) > Else > lHigh = CLng(TempHigh) > lLow = CLng(TempLow) > End If > End Sub > > > Rick > > What about using the Currency data type instead of Decimal? Decimal is only
half supported by VB (via Variant), whereas Currency is already in a fixed-point binary format and so is much easier to separate into high/low portions Tony Proctor Show quoteHide quote "Lorin" <Lo***@discussions.microsoft.com> wrote in message news:E8E5F76A-2F80-4873-A700-D4E21D07325B@microsoft.com... > > > "Lorin" wrote: > > > Need to convert a Decimal(Variant) to two longs. > > Dim vNbr as Variant > > Dim vNbr1 as Variant > > Dim vNbr2 as Variant > > > > vNbr = CDec(0) > > vNbr1 = CDec(123456) ' e.g. > > vNbr2 = CDec(987654) > > vNbr = vNbr1 * vNbr2 > > > > ' Now I need the Decimal Variant broken into two Longs. > > The Sub might look like, returninh lHi and lLo > > Public Sub Convert(vNbr as Variant, lHo as Long, lLo as long) > > ... > > End Sub > > > > The Decimal(variant) will never be greater that what two longs can hold. > To make it clearer ... > I will be incrementing the Decimal and using the result to set the pointer > for a file operation. e.g. a DVD .iso file. > The file can be much longer than 2G so this is the need to handle larger > than one long. > > > The syntax is > lRet = SetFilePointer(m_hFile, lOffsetLo, lOffsetHi, FILE_CURRENT) >
Other interesting topics
|
|||||||||||||||||||||||