# Faking 64-bit Integers

## Introduction

Usually, the intrinsic Visual Basic data types are sufficient to read information from and send information to API functions. The two most important and frequently used data types are String and Long, which is a 32-bit integer data type. Since Windows is a 32-bit operating system, it almost exclusively uses 32-bit integers throughout its API.

However, 32 bits of integer data are not always enough. For some functions, a 64-bit integer data type is necessary to encompass the entire range of possible information. The ULARGE_INTEGER structure used by the API stores such a 64-bit integer by separating it into high-order and low-order halves of 32 bits each. This format is, sadly, not convenient for actually reading the data in the structure. To easily read and write to these structures, a 64-bit integer data type is necessary. And alas, Visual Basic has no true 64-bit integer data type.

## The Currency Data Type

Fortunately, all is not lost! Visual Basic has the Currency data type. The Currency data type was initially created by the designers of Visual Basic to allow precise computations to be made on monetary values. The Single and Double floating-point data types are insufficient because they can only support a limited number of significant digits. Beyond that number of digits, some rounding occurs. The Currency data type combines the exactness of integer data types with a few fixed decimal places to allow subdivisions of a currency unit (such as a cent).

Internally, the Currency data type actually is a 64-bit integer. However, Visual Basic scales down by a factor of 10,000 to produce four digits after the decimal point. So, although the data type is a 64-bit integer, Visual Basic will display the value of any Currency-type variable as having a decimal point followed by four digits. Therefore, in order to display a 64-bit value copied into the variable correctly, you must first multiply the variable by 10,000. This will shift the decimal point four places to the right, resulting in the display of the actual value.

## Example

Here is an example of how the Currency data type can be used to display a 64-bit integer retrieved from an API function. The GetDiskFreeSpaceEx reports all of its data as 64-bit integers. For disk space, 32-bit integers are too small; otherwise, the function would be limited to hard drives having a total storage space of less than 4.0 GB. Clearly, this is too small for modern disks!

After retrieving the information from the function, the following code copies it into a Currency-type variable. Then, after multiplying it by 10000 to move Visual Basic's decimal point, the free space of drive C: is properly stated.

``````Dim userbytes As ULARGE_INTEGER  ' bytes free to user
Dim totalbytes As ULARGE_INTEGER  ' total bytes on disk
Dim freebytes As ULARGE_INTEGER  ' free bytes on disk
Dim tempval As Currency  ' display buffer for 64-bit values
Dim retval As Long  ' return value of function

' Get information about the C: drive.
retval = GetDiskFreeSpaceEx("C:\", userbytes, totalbytes, freebytes)
' Copy totalbytes into the Currency data type.
CopyMemory tempval, totalbytes, 8
' Multiply by 10000 to move Visual Basic's decimal point to the end of the actual number.
tempval = tempval * 10000
' Display the total number of bytes on C:.
Debug.Print "Free Space on the C: drive:"; tempval; "bytes"``````

## Manipulating 64-bit Integers

Although you may be storing a true 64-bit integer inside a Currency data type, Visual Basic believes there is a decimal point inside the value whether you want one there or not. Therefore, you must take care when performing some arithmetic operations on true 64-bit values. This involves moving the decimal point to preserve the actual integer, instead of the value Visual Basic believes you are storing inside of it.

No conversion factor is necessary to add or subtract 64-bit integers from one another. Simply add or subtract Currency types as you would any other data type values.

### Multiplication

When multiplying two 64-bit integers in Currency form, you must multiply the result by 10,000 to move the decimal point to the proper place. However, if you wait to multiply by 10,000 until after you calculate the initial product, it is very possible that you will have lost part of the calculation due to internal rounding off. Therefore, to multiply two 64-bit integers in Currency form, use the following formula:

product = 10000 * first * second

### Division

Like multiplication, division of two 64-bit integers in Currency form requires a correction factor. However, in this case, the quotient must be divided by 10,000. To minimize internal rounding off of significant digits, you should divide by 10,000 only after calculating the initial quotient. To divide two 64-bit integers in Currency form, use the following formula:

quotient = dividend / divisor / 10000

### Limitations

Although using the Currency data type to "fake" 64-bit integer support in Visual Basic should work in most cases, there remains the problem of data range. Because the value must be multiplied by 10,000 to display properly, values at the extremes of the 64-bit integer range will cause an Overflow error if you try to display them. Thus, the Currency form of 64-bit integers in Visual Basic has a display range from -372,036,854,775,808 to 372,036,854,775,807. So while you cannot use the full range of 64-bit values, nevertheless these fake 64-bit integers greatly extend the range offered by the intrinsic 32-bit data type.

Of course, this limitation does not apply to 64-bit integers that do not need to be displayed for the user. The Currency data type itself can store the entire 64-bit range from -9,223,372,036,854,775,808 to 9,223,372,036,854,775,807. Note, however, that at these extremes, the methods presented earlier for multiplying and dividing these values may fail. They depend on having the "extra room" available in the storage space that may not be present past the trillions. Again, however, despite these limitations, using the Currency data type as a pseudo-64-bit integer data type makes it significantly easier to use those API functions that, like GetDiskFreeSpaceEx, use 64-bit values in their parameters.

Back to the Article list.