
Dec 16th, 2012, 08:13 PM
#1
Thread Starter
Hyperactive Member
VB6  Fast Inverse Sqrt
a=1/Sqr(b) is an high time consuming operation.
This function is intensively used in vector operation, such normalization:
eg: D=sqr(dx*dx+dy*dy) , dx=dx/d , dy=dy/d
In C and other languages there's a technique to do this opertation in a fast way called
fast inverse square root
Look here and here.
Code:
float InvSqrt(float x)
{
float xhalf = 0.5f*x;
int i = *(int*)&x; // get bits for floating value
i = 0x5f375a86 (i>>1); // gives initial guess y0
x = *(float*)&i; // convert bits back to float
x = x*(1.5fxhalf*x*x); // Newton step, repeating increases accuracy
return x;
}
Code:
public static float invSqrt(float x) {
float xhalf = 0.5f*x;
int i = Float.floatToIntBits(x);
i = 0x5f3759df  (i>>1);
x = Float.intBitsToFloat(i);
x = x*(1.5f  xhalf*x*x);
return x;
}
Don't know if it could worth to translate these codes to VB6 and if the new (VB6) InvSqrt function could be faster than
1/Sqr(b).
Could someone Help about this?
(Sorry for my english)

Dec 17th, 2012, 08:24 AM
#2
Thread Starter
Hyperactive Member
Re: VB6  Fast Inverse Sqrt
I found Solution:
Code:
Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (pDst As Any, pSrc As Any, ByVal ByteLen As Long)
Public Function InvSQR(number As Single) As Single
Dim I As Long
Dim X2 As Single
Dim Y As Single
Const threehalfs As Single = 1.5
Debug.Print Len(I), Len(Y)
X2 = number * 0.5
Y = number
CopyMemory I, Y, 4
I = &H5F3759DF  (I \ 2)
CopyMemory Y, I, 4
Y = Y * (threehalfs  (X2 * Y * Y))
InvSQR = Y
End Function
(at the moment don't know about speed)

Dec 17th, 2012, 12:39 PM
#3
Re: VB6  Fast Inverse Sqrt
Code:
Private Declare Sub GetMem4 Lib "msvbvm60.dll" (ByVal Ptr As Long, ByRef RetVal As Any)
Public Function InvSQR(ByVal X As Single) As Single
Dim I As Long, XHalf As Single
XHalf = 0.5! * X
GetMem4 VarPtr(X), I
I = &H5F3759DF  (I * 0.5!)
GetMem4 VarPtr(I), X
InvSQR = X * (1.5!  XHalf * X * X)
End Function
The API call can be optimized by declaring it in a Type Library. Check out Michel Rutten's Visual Basic 6 Virtual Machine Type Library which contains custom GetMem declares.
On Local Error Resume Next: If Not Empty Is Nothing Then Do While Null: ReDim i(True To False) As Currency: Loop: Else Debug.Assert CCur(CLng(CInt(CBool(False Imp True Xor False Eqv True)))): Stop: On Local Error GoTo 0
Declare Sub CrashVB Lib "msvbvm60" (Optional DontPassMe As Any)

Dec 21st, 2012, 06:01 AM
#4
Thread Starter
Hyperactive Member
Re: VB6  Fast Inverse Sqrt

Aug 3rd, 2013, 06:43 AM
#5
Thread Starter
Hyperactive Member
Re: VB6  Fast Inverse Sqrt
Public Function InvSQR(ByVal X As Single) As Single
please could you find this function for DOUBLE types:
Public Function InvSQR(ByVal X As Double) As Double
thanks

Aug 3rd, 2013, 07:50 AM
#6
Re: VB6  Fast Inverse Sqrt
I have no idea if this will work, but you could try replacing GetMem4 with GetMem8 and promoting all the Single values and variables in the function in post #3 to Double. Here is GetMem8's declare:
Code:
Private Declare Sub GetMem8 Lib "msvbvm60.dll" (ByVal Ptr As Long, ByRef RetVal As Any)
On Local Error Resume Next: If Not Empty Is Nothing Then Do While Null: ReDim i(True To False) As Currency: Loop: Else Debug.Assert CCur(CLng(CInt(CBool(False Imp True Xor False Eqv True)))): Stop: On Local Error GoTo 0
Declare Sub CrashVB Lib "msvbvm60" (Optional DontPassMe As Any)
Posting Permissions
 You may not post new threads
 You may not post replies
 You may not post attachments
 You may not edit your posts

Forum Rules

Click Here to Expand Forum to Full Width
