Professional Documents
Culture Documents
This Workbook Holds The Latest Version of Our Implementation of FMRG, Which Can Be Used Via The Formula RANDOM
This Workbook Holds The Latest Version of Our Implementation of FMRG, Which Can Be Used Via The Formula RANDOM
=RANDOM()
Hit F9 to recalculate
------------------------------------------------------------------------
Introduction
Usually, the intrinsic Visual Basic data types are sufficient to read information from and send information to API functions. The two most i
However, 32 bits of integer data are not always enough. For some functions, a 64-bit integer data type is necessary to encompass the en
Fortunately, all is not lost! Visual Basic has the Currency data type. The Currency data type was initially created by the designers of Visu
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 dig
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 GetDiskFre
After retrieving the information from the function, the following code copies it into a Currency-type variable. Then, after multiplying it by 1
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
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 va
No conversion factor is necessary to add or subtract 64-bit integers from one another. Simply add or subtract Currency types as you wou
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 pla
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 b
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 prob
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
Back to the Article list.
------------------------------------------------------------------------
Last Modified: XXUPDATEXX
This page is copyright © 2000 Paul Kuliniewicz. Copyright Information
Go back to the Windows API Guide home page.
E-mail: vbapi@vbapi.com Send Encrypted E-Mail
This page is at http://www.vbapi.com/articles/64bit/index.html
ion 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
e is necessary to encompass the entire range of possible information. The ULARGE_INTEGER structure used by the API stores such a 64-bit integer b
ally created by the designers of Visual Basic to allow precise computations to be made on monetary values. The Single and Double floating-point data t
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 C
om 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 func
iable. Then, after multiplying it by 10000 to move Visual Basic's decimal point, the free space of drive C: is properly stated.
here is a decimal point inside the value whether you want one there or not. Therefore, you must take care when performing some arithmetic operations
subtract Currency types as you would any other data type values.
e 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
ver, 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 ca
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 th
er. 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
nteger data type. Since Windows is a 32-bit operating system, it almost exclusively uses 32-bit integers throughout its API.
he 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 actuall
gle and Double floating-point data types are insufficient because they can only support a limited number of significant digits. Beyond that number of dig
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
rs 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 m
rforming some arithmetic operations on true 64-bit values. This involves moving the decimal point to preserve the actual integer, instead of the value Vi
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 Currenc
hould divide by 10,000 only after calculating the initial quotient. To divide two 64-bit integers in Currency form, use the following formula:
operly, 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 integ
6,854,775,807. Note, however, that at these extremes, the methods presented earlier for multiplying and dividing these values may fail. They depend o
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 necessa
nt digits. Beyond that number of digits, some rounding occurs. The Currency data type combines the exactness of integer data types with a few fixed d
re, 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
ctual integer, instead of the value Visual Basic believes you are storing inside of it.
ultiply two 64-bit integers in Currency form, use the following formula:
he following formula:
us, 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 us
ese 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, d
a 64-bit integer data type is necessary. And alas, Visual Basic has no true 64-bit integer data type.
nteger data types with a few fixed decimal places to allow subdivisions of a currency unit (such as a cent).
This will shift the decimal point four places to the right, resulting in the display of the actual value.
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 intr
t past the trillions. Again, however, despite these limitations, using the Currency data type as a pseudo-64-bit integer data type makes it significantly ea
extend the range offered by the intrinsic 32-bit data type.
er data type makes it significantly easier to use those API functions that, like GetDiskFreeSpaceEx, use 64-bit values in their parameters.
s in their parameters.
Variable Var1 52 52
Number Obs 10000 Histogram of Var1
Number Non-missing 10000
Number Missing 0
Number of Unique values 10000
Mean 0,0
SD 5,0
Min -5,0
25th Percentile -3,6
Median -1,5
75th Percentile 1,8
Max 46,2
-5 5 15 25 35 45
Histogram of $B$66
-9,5 0
-9,5 1
-9 1
-9 0
-8,5 0
-8,5 1
-8 1
-8 0
-7,5 0
-7,5 0
-7 0
-7 0
-6,5 0
-6,5 1
-6 1
-6 0
-5,5 0
-5,5 2
-5 2
-5 2
-4,5 2
-4,5 2
-4 2
-4 6
-3,5 6
-3,5 8
-3 8
-3 9
-2,5 9
-2,5 19
-2 19
-2 50
-1,5 50
-1,5 89
-1 89
-1 136
-0,5 136
-0,5 199
0 199
0 174
0,5 174
0,5 127
1 127
1 71
1,5 71
1,5 48
2 48
2 21
2,5 21
2,5 11
3 11
3 10
3,5 10
3,5 6
4 6
4 3
4,5 3
4,5 2
5 2
5 1
5,5 1
5,5 0
6 0
6 1
6,5 1
6,5 0
This sheet documents and demonstrates two array functions which generate correlated normal random variables.
Function BiVarNormal(mean1 As Double, SD1 As Double, mean2 As Double, SD2 As Double, rho As Double) As Variant
Function MultivarNormal(nvars As Integer, corrRange As Range, meansRange As Range, SDsrange As Range) As Variant
The functions are volatile.
MultivarNormal requires ranges as input.
corrRange contains the correlation matrix for the random variables--only the lower triangular part is used.
meansRange contains the vector of means.
SDsRange contains the vector of SDs.
Both meansRange and SDsRange must be column vectors.
The output is a row vector.
Up to 256 correlated normals are allowed. As n increases, so does computation time. Since the function is
volatile, it recalculates every time you make a change to the Excel sheet. This can slow things down considerably.
One remedy is to use Tools:Options:Calculation to set calculation to manual.
Error handling:
We guard against negative SDs.
We guard against correlations which are greater than 1.
For Multivar, there is an error message box that warns if the variance-covariance matrix isn't positive definite and no
In Multivar, we check to see that all the diagonal entries are 1.
We check to see that the arrays all have the proper dimensions.
Examples
Bivar: #VALUE! #VALUE! #VALUE! I use the GetFormula macro to indicate what these formulas
CorrRange MeansRangeSDsRange
1 0 1
0,2 1 10 1
0,3 0,4 1 100 1
Run MCSim.xla on the Output Testing cells to see that they match the user input.
BiVarNormal MultiVarNormal
corrRange meansRange SDsRange
{=BiVarNormal(0, 1, 0, 2, 0.9)} 1 0 1
0,9 1 10 1
0,1 0,5 1 20 1
As Double) As Variant
nge As Range) As Variant
own considerably.
29 mai 98 Changed Function pivotValue to deal with Qsort's problems with already sorted lists
Old version of Function is pivotValueOld.
I've written a revision to Function pivotValue in the random number and sorting module. The old version is
stored as Function pivotValueOld in case we need to go back to it. I've tested my revision and it seems to
I didn't time it, but I think that it's slower because of extra steps in the new version (finding the median of th
The old version very mechanically picked a pivot value (the value which is used to divide the list in two
--everything bigger goes into one list, everything smaller into another). This caused problems for lists that
The new version takes as the pivot value the median of three numbers, x(left), x (right), and x(middle)
where x() is the list being sorted and left is the first element of the list, right is the last and middle is in the m
E.g. if you are currently sorting x(50) through x(100) the pivot value would be based on the median of
x(50), x(100) and x(75). The function actually returns an integer. Suppose
x(50) = 1000
x(75) = 1200
x(100) = 995.
Then x(50) is the median value and the function would return 50.
Qsort then takes x(50) as the value which it will use as the value to make a partition of the original set.
The key code is here
p = pivotValue(x, l, r, M) [the function I revised]
If (p <> -1) Then [when p = -1, there's nothing to sort, so don't do what follows]
pv = x(p, M) [this would make pv = 1000 in my example above]
Call MyPartition(x, l, r, pv, k, n, M) [this reorders the list to put to the left everything
below 1000 and to the right everything above 1000]
All this is nicely explained along with a helpful diagram in Mark Allen Weiss, Data Structures and Algorithm
1994, Benjamin/Cummings, pp. 267-270. The MyPartition subroutine seems to follow Weiss's section 7.7.
FH
9 iun 98 Further refinements are to check to be sure that the pivot value is the larger one if there 2 of the 3 values in
method are equal, and to reject the method in favor of the original one in PivotValueOld if all 3 values are e
7-Feb-2004
Changed NORMALRANDOM to force use of FMRG and allow SD=0
You must provide mean and SD. SD=0 can be used.
28 oct 04
Added (quasi) Exponential functions.
Function Expo(Mean As Double, SD As Double) As Double
Sub ExponentialRNG(ExponentialRand() As Double, Mean As Double, SD As Double)
Generates a vector of quasi-exponential RVs with desired mean and double
These are just rescaling and shifts of the Exponential(lambda=1) random variable.
17 febr 05
Fixed problem with NORMALRANDOM--it was accepting negative SDs.
Same problem with Expo
Same problem with NORMALRANDOM
NORMALRANDOM #VALUE! #VALUE!
Expo #VALUE! #VALUE!
Uniform #VALUE! #VALUE!
28 mar 05
Added Histogram Module to Random.xls.
The code contains a fix for the problem when Width is zero. This occurs when the variable is constant.
The problem is fixed by making the Width= 1. That width can be changed in the two histogram case.
FH
17 iun 05
Added
Function BiVarNormal(mean1 As Double, SD1 As Double, mean2 As Double, SD2 As Double, rho As Double) As Variant
Function MultivarNormal(nvars As Integer, corrRange As Range, meansRange As Range, SDsrange As Range) As Variant
in Functions module.
These functions enable draws from bi- and multivariate normal distributions.
See the sheet CorrelatedRVs for more.
7 iul 05
Added more explanation to correlated RVs sheet.
Added MultiVarNormalTester macro.
Confirmed that MutliVarNormal worked with n=256.
5 mar 06
Added the array function LINESTA: usage is just like LINEST except it runs regression using only Y > 0 values (as in, for example, a censore
15 mar 06
Added the array functions RandomSample(PopRange, n, WithoutReplacement? Optional, Default is True) and RandomSampleNV (the non-
Hit F9 to recalculate and see the function in action. Click on one of the cells to see the function arguments.
Draw from Draw from
2nd column 2nd and 3rd
w/o columns w/o
Population replacement replacement
1 10 100 #VALUE! #VALUE! #VALUE!
2 20 200 #VALUE! #VALUE! #VALUE!
3 30 300 #VALUE! #VALUE! #VALUE!
4 40 400 #VALUE!
Draw from
2nd column
w/o
replacement
NV version
#VALUE! Hitting F9 does not change this function
#VALUE! To force a recalculation, hit CTRL-ALT-F9
#VALUE! Use MCSimNV with this version of the function
#VALUE!
To use these functions, you must have this workbook open and use the formula "=RANDOM.XLS!RandomSample(cellrangeofpopulation,sam
The RANDOM.XLS part of the formula tells Excel where to find the function (i.e., in this open workbook).
For permament access to the function in another workbook, execute Alt-F11 and drag the Functions module from this workbook to your work
18 apr 06
Added the array functions Function MultivarXs(nvars, nobs, corrRange, meansRange , SDsrange) and MultivarXsV (the volatile version of th
Correlation Matrix
#VALUE!
#VALUE! #VALUE!
#VALUE! #VALUE! #VALUE!
These functions are limited by the limits of LINEST. That means that one cannot produce more than 16 variables.
8 iun 06
Added logit and probit functions
x y logit probit
-1 1 #VALUE! #VALUE! #VALUE! #VALUE!
-0,9 1 #VALUE! #VALUE! #VALUE! #VALUE!
-0,8 1 #VALUE! #VALUE! #VALUE! #VALUE!
-0,7 1
-0,6 1 Hit F9 repeatedly, with perfect classification, probit gives #VALUE, but logit does not.
-0,5 1 'The functions are
-0,4 1 ' =logit(xRange, yRange, Optional 0/1 for Intercept with 1 as default)
-0,3 0 ' =probit(xRange, yRange, Optional 0/1 for Intercept with 1 as default)
-0,2 1 'Example
-0,1 0 ' =logit(A2:C101,D2:D101) is the same as =logit(A2:C101,D2:D101,1)
24 aug 06
Modified LINESTA function to handle missing values (either blank cells or with periods, ".")
Example: =LINESTA(YRange, XRange, 0/1 for constant, 0/1 for stats, Optional 1, 1 is default) to run regression on Y>0 values
Example: =LINESTA(YRange, XRange, 1 for constant, 1 for stats, 2) to run regression with on data with missing values (either blank cells or
x y when Y or X is missing, LINEST fails LINESTA with YType parameter set equal to
1 1 Err:502 Err:502 #VALUE! #VALUE!
2 Err:502 Err:502 #VALUE! #VALUE!
3 . Err:502 Err:502 #VALUE! #VALUE!
4 4 Err:502 Err:502 #VALUE! #VALUE!
5 5 Err:502 Err:502 #VALUE! #VALUE!
2 mar 07
Corrected error inVecMatVecMult routine
For i = 1 To n
xtemp(i, 1) = X(i) This said X(1) instead of X(i)
Next i
ng module. The old version is
d my revision and it seems to sort successfully.
rsion (finding the median of three, described below)
s Double) As Variant
e As Range) As Variant
Correlation Matrix
#VALUE!
#VALUE! #VALUE!
#VALUE! #VALUE! #VALUE!
UE, but logit does not.
n on Y>0 values
ng values (either blank cells or periods)
YType parameter set equal to 2, ignores the missing data in the blank (or with periods) Y or X cells
click on a cell to the left to see the LINESTA formula