I wrote the following C function which displays the binary
representation of a float. I wish to write a similar thing in VB. is
there a way of casting in VB (without loosing the floating point
representation) to access the float bits as I did in the following
function?
thanks
Arnon
void bin(float f)
{
int i=0;
unsigned long j,* ff;
ff = (unsigned long *)&f;
for (j=2147483648 ; j>=1 ; j/=2)
printf("%d",(((*ff)&j)) ? 1 : 0);
printf("\n");
}
>I wrote the following C function which displays the binary
>representation of a float. I wish to write a similar thing in VB. is
>there a way of casting in VB (without loosing the floating point
>representation) to access the float bits as I did in the following
>function?
Here is a function to convert the float to a string using the Windows API
function to copy the bytes from one variable to the other. It duplicates the
DOS BASIC MKS$ function that has been removed from VB.
The Test routine displays the values of the 4 bytes. If you want to see the
value in binary, you can probably get there by manipulating the bytes of the
string.
Just curious, but why are you doing this?
Declare Sub CopyMemory Lib "KERNEL32" Alias "RtlMoveMemory" _
(lpvDest As Any, lpvSource As Any, ByVal NumBytes As Long)
Function SingleToString(ByVal SPFloat As Single) As String
Dim sTemp As String
sTemp = String$(4, 0)
CopyMemory ByVal sTemp, SPFloat, 4
SingleToString = sTemp
End Function
Sub Test()
Dim X As Single
Dim s As String
Dim i As Long
Randomize
X = Rnd()
s = SingleToString(X)
For i = 1 To 4
Debug.Print Asc(Mid$(s, i, 1)),
Next i
Debug.Print
End Sub
Here are the corresponding routines to convert from a single to a long
integer. But you will have problems with the Test routine if the highest bit
of the single is set, because that's the sign bit, and Basic doesn't have an
unsigned long integer type.
You can also do this with UDT variables and the LSET command, as illustrated
in the 2nd set of routines, where I also show how to get around the problem of
the sign bit.
Declare Sub CopyMemory Lib "KERNEL32" Alias "RtlMoveMemory" _
(lpvDest As Any, lpvSource As Any, ByVal NumBytes As Long)
Function SingleToLong(ByVal SPFloat As Single) As Long
Dim LLong As Long
CopyMemory LLong, SPFloat, 4
SingleToLong = LLong
End Function
Sub Test()
Dim X As Single
Dim L As Long
Dim i As Long
Randomize
X = Rnd()
L = SingleToLong(X)
For i = 1 To 32
Debug.Print (L And 1)
L = L \ 2
Next i
Debug.Print
End Sub
~~~~~~~~~~~~~~~~~~~~
Type SingleType
X As Single
End Type
Type StringType
X As String * 4
End Type
Function SingleToString2(ByVal SPFloat As Single) As String
Dim v1 As SingleType
Dim v2 As StringType
v1.X = SPFloat
LSet v2 = v1
SingleToString2 = v2.X
End Function
Sub Test2()
Dim X As Single
Dim S As String
Dim i As Long
Dim Ch As String
Dim J As Long
Randomize
X = Rnd()
S = SingleToString2(X)
Debug.Print X
For i = 1 To 4
Ch = Asc(Mid$(S, i, 1))
For J = 1 To 8
Debug.Print (Ch And 1);
Ch = Ch \ 2
Next J
In Excel VBA, there isn't the unsigned integer type, as far as I know.
The following is an example,
Type TSingle
Value As Single
End Type
Type TLong
Value As Long
End Type
Function SingleToLong(f As Single) As Long
Dim a As TSingle
Dim b As TLong
a.Value = f
LSet b = a
SingleToLong = b.Value
End Function
Function SingleToBin(f As Single) As String
Dim l As Long
Dim j As Long
Dim s As String
l = SingleToLong(f)
If (l And &H80000000) = 0 Then
s = "0"
Else
s = "1"
End If
j = &H40000000
Do While j >= 1
If (l And j) = 0 Then
s = s & "0"
Else
s = s & "1"
End If
j = j \ 2
Loop
SingleToBin = s
End Function
Sub Test()
Debug.Print SingleToBin(0.1)
End Sub
Regards,
Kazuyuki Housaka
hou...@po1.cnet-na.ne.jp
Arnon wrote:
>
> I wrote the following C function which displays the binary
> representation of a float. I wish to write a similar thing in VB. is
> there a way of casting in VB (without loosing the floating point
> representation) to access the float bits as I did in the following
> function?
> void bin(float f)