Home All Groups Group Topic Archive Search About
Author
10 May 2007 7:02 PM
Lorin
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

Author
10 May 2007 7:30 PM
MikeD
Show quote Hide quote
"Lorin" <Lo***@discussions.microsoft.com> wrote in message
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)


You mean split a Long into its hi and low words?

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
Are all your drivers up to date? click for free checkup

Author
10 May 2007 7:34 PM
Rick Rothstein (MVP - VB)
Show quote Hide quote
> 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

You are aware that the Decimal data type can hold numbers bigger than two
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
Author
10 May 2007 8:05 PM
Mike Williams
Show quote Hide quote
"Lorin" <Lo***@discussions.microsoft.com> wrote in message
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

As Rick has already said, are you aware that the byte size of a Decimal is
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
Author
10 May 2007 11:26 PM
Lorin
Show quote Hide quote
"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)
Author
11 May 2007 3:23 AM
Rick Rothstein (MVP - VB)
Show quote Hide quote
>> 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
Author
11 May 2007 6:35 PM
Lorin
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
>
>
Author
11 May 2007 11:31 AM
Tony Proctor
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)
>

Bookmark and Share