# VBForums CodeBank > CodeBank - Visual Basic 6 and earlier >  LongLong (LL) self-instantiating Class (CLS module) using Currency

## Elroy

(Thanks go out to *The Trick* for working on the LongLong multiplication, and to *Krool* for a careful reading of my comments.)

This has been bantered around many times, and I've wanted to do it for a while.  So, here it is.

It's a self-instantiating class.  (VB_PredeclaredId=True, no need to declare and/or instantiate an object variable, just use it.)

You can toss the LL.cls class module into any project you like, and then you'll have rather complete LongLong support.

The only bit of a mind-warp is that you must declare your LongLong variables as Currency (as we've got no LongLong type).

So long as your API declaration is declared with "As Currency" for the LongLongs, you can even use these in API calls expecting the LongLong type.

Once declared, and you access them (assign, output, print) _only_ with the functions in the LL class, they'll behave exactly like the LongLong variables seen in the VBA.

I'm developing a habit of using a "ll" prefix on these variables, for example:



```
Dim llTest1 As Currency
Dim llSomethingElse As Currency
```

This helps me to keep things straight.

Here's the header documentation on the LL.cls.



```
'
' Documentation:
'   This is a self-instantiating (VB_PredeclaredId=True) class (named LL or LL.cls) that treats Currency types
'   as if they're LongLong types.  If you use the create/assign (casting) functions provided herein,
'   as well as the output/reporting functions herein, these Currency types will appear and work as LongLongs.
'   They can even be passed to API calls as LongLong when required, if the API declaration is declared "As Currency"
'   for the required argument(s).
'
'   Create/assign functions:
'       LL.FromStr(ByVal s As String) As Currency  ' Handles full range of + & - for LongLong.  Returns LongLong sitting in Currency.
'       LL.FromHex(h As String) As Currency        ' Anything smaller than &h8000000000000000 is positive.  Returns LongLong sitting in Currency.
'       LL.FromInt(i As Integer) As Currency       ' Returns LongLong sitting in Currency.
'       LL.FromLng(l As Long) As Currency          ' Returns LongLong sitting in Currency.
'       LL.FromDec(v As Variant) As Currency       ' Returns LongLong sitting in Currency.  Input must be vbDecimal type.  Rounds any fraction.
'       LL.FromDbl(d As Double) As Currency        ' Returns LongLong sitting in Currency.  Rounds any fraction.
'       LL.FromSng(f As Single) As Currency        ' Returns LongLong sitting in Currency.  Rounds any fraction.
'       LL.Random(...) As Currency                 ' Returns a completely random LongLong sitting in a Currency.
'
'   Math functions:
'       LL.Sum(ll1 As Currency, ll2 As Currency) As Currency       ' Adds two LongLongs, returns LongLong sitting in a Currency.
'       LL.Diff(ll1 As Currency, ll2 As Currency) As Currency      ' Subtracts two LongLongs, returns LongLong sitting in a Currency.
'       LL.Mult(ll1 As Currency, ll2 As Currency) As Currency      ' Multiplies two LongLongs, returns LongLong sitting in a Currency.
'       LL.Div(ll1 As Currency, ll2 As Currency) As Currency       ' Divides two LongLongs, returns LongLong sitting in a Currency.  Integer-type division (rounding toward 0).
'       LL.DblMult(ll1 As Currency, ll2 As Currency) As Double     ' Multiplies two LongLongs, returning Double with fraction.
'       LL.SngMult(ll1 As Currency, ll2 As Currency) As Single     ' Multiplies two LongLongs, returning Single with fraction.
'       LL.DecMult(ll1 As Currency, ll2 As Currency) As Variant    ' Multiplies two LongLongs, returning Decimal (Variant) with fraction.
'       LL.DblDiv(ll1 As Currency, ll2 As Currency) As Double      ' Divides two LongLongs, returning Double with fraction.
'       LL.SngDiv(ll1 As Currency, ll2 As Currency) As Single      ' Divides two LongLongs, returning Single with fraction.
'       LL.DecDiv(ll1 As Currency, ll2 As Currency) As Variant     ' Divides two LongLongs, returning Decimal (Variant) with fraction.
'       LL.Modulus(ll1 As Currency, ll2 As Currency) As Currency   ' Returns remainder, LongLong sitting in a Currency.
'       LL.Inc(llValue As Currency) As Currency                    ' Adds 1, LongLong sitting in a Currency.
'       LL.Dec(llValue As Currency) As Currency                    ' Subtracts 1, LongLong sitting in a Currency.
'       LL.Sign(llValue As Currency) As Currency                   ' Returns 1, -1, or 0 as a LongLong sitting in a Currency.
'       LL.AbsVal(llValue As Currency) As Currency                 ' As it says.
'       LL.Pow(llBase As Currency, bbExp As Byte) As Currency      ' A power (^) function, for LongLong, with Byte exponent.
'
'   Bit manipulation functions:
'       LL.ShiftLeft(llBase As Currency, lBitsToShift As Long) As Currency
'       LL.ShiftRight(llBase As Currency, lBitsToShift As Long) As Currency         ' See comments in function.
'       LL.ShiftRightArith(llBase As Currency, lBitsToShift As Long) As Currency    ' See comments in function.
'       LL.BitNot(llValue As Currency) As Currency                 ' 1s complement of input.
'       LL.BitAnd(ll1 As Currency, ll2 As Currency) As Currency    ' Bitwise AND operation.
'       LL.BitOr(ll1 As Currency, ll2 As Currency) As Currency     ' Bitwise OR operation.
'       LL.BitXor(ll1 As Currency, ll2 As Currency) As Currency    ' Bitwise XOR operation.
'       LL.BitEqv(ll1 As Currency, ll2 As Currency) As Currency    ' Bitwise EQV operation.
'       LL.BitImp(ll1 As Currency, ll2 As Currency) As Currency    ' Bitwise IMP operation.
'
'   Output/report functions:
'       LL.ToDec(llValue As Currency) As Variant                               ' Similar to CDec() but input is LongLong sitting in Currency.
'       LL.ToLong(llValue As Currency) As Long                                 ' Similar to CLng() but input is LongLong sitting in Currency.
'       LL.ToInt(llValue As Currency) As Integer                               ' Similar to CInt() but input is LongLong sitting in Currency.
'       LL.ToDbl(llValue As Currency) As Double                                ' Similar to CDbl() but input is LongLong sitting in Currency.
'       LL.ToSng(llValue As Currency) As Single                                ' Similar to CSng() but input is LongLong sitting in Currency.
'       LL.ToHex(llValue As Currency) As String                                ' Works like Hex$() function, but input is LongLong sitting in Currency.
'       LL.ToStr(llValue As Currency) As String                                ' Works like CStr() function, but input is LongLong sitting in Currency.
'       LL.Format(llValue As Currency, Optional sFormat As String) As String   ' Works like VBA.Format$() function, but input is LongLong sitting in Currency.

```

There is also a Form1 in the attached project that I used for some testing of various edge conditions.  I also extensively tested all the other functions, but that testing isn't provided.  But you can ignore all but the LL.cls file if you like.  That's all you'll need to get LongLongs in your VB6 project.

--------------------

I'm receptive to any comments/critiques anyone has, and I'll probably be releasing other versions later.

Also, please let me know if you need another function, for instance a Pow() function.

--------------------

Once this is out there for a while, I'll probably also do a ULL.cls (unsigned uint64 bit version).  I suppose an unsigned uint32 bit version might also be useful (unsigned Long), and maybe even a uint16 bit version.

Enjoy

*Update to v1.002*: Cleaned up a few of the comments, and fixed a bug such that division by zero now returns error 11.
*Update to v1.004*: Sped up LL.Inc, LL.Dec, LL.ToStr, & LL.Format a bit, added a LL.Pow() function, and fixed bug in LL.Random function.

----------


## dz32

Another possibility would be to store the value in a class instance and name the class long long 
Then all the methods would be implicitly available for each instance and the base value could be removed as an second argument 
Also the methods could return the result in a new class instance so you could chain operations.

 Value could be default property of class. Arg to the functions could be variant and take literal numeric value, hex string or another long long class instance



```
Dim a as new CLongLong
dim b as CLongLong
dim C as CLongLong

a = "0x1122334455667788"  'default property of class is .value accepts multiple types
set b = a.Add(&h11223344)
msgbox b.toString()

set b = a.subtract(b)
if a <> b then msgbox "Error"

set c = a.add(b).subtract(b)
if a <> c then msgbox "Error"
```

the extra set command is slightly annoying, and it will take up some extra memory with the class instances, but very convenient to use and the default .value property makes it as close to a native type as you can get.

----------


## Elroy

> Another possibility would be to store the value in a class instance and name the class long long 
> Then all the methods would be implicitly available for each instance and the base value could be removed as an second argument 
> Also the methods could return the result in a new class instance so you could chain operations.
> 
>  Value could be default property of class. Arg to the functions could be variant and take literal numeric value, hex string or another long long class instance
> 
> 
> 
> ```
> ...


I actually thought about that, and actually started development of such a class.  I just didn't want the overhead of a class for each LongLong variable I declare.  A Currency is a true native type, taking only 8 bytes.  Actually, I might see if I can develop a TypeLib that provides a cLongLong that's actually a Currency.  That might help some, but it's really just not necessary.

----------


## fafalone

Lots of LongLong stuff coming out recently, I like it  :Smilie: 

Similar to this, I made a standard DLL for VB6 in twinBASIC for LongLong support... tB supports LongLong natively, so I just declare the functions as LongLong in tB, then Currency in VB6.

https://github.com/fafalone/LongLongHelper

----------


## Krool

In your header doc LL.DecMult and LL.DecDiv return As Single instead of As Variant.

----------


## Elroy

> In your header doc LL.DecMult and LL.DecDiv return As Single instead of As Variant.


Ahhh, thanks.  I've also got another small bug (not erroring on divide by zero).  I'll post an update later today.  I also want to work in The Trick's thunk for LL.Mult, but I'm not sure I'll get that done today.

----------

