Here is some VB code to go from an IEEE 754 single to 4 bytes and back to a single. It is indeed the hard way to do it. I wrote this before the "unsafe" bitconverter appeared on the scene, but now use the unsafe BC and have never had problems with it.
Imports Microsoft.SPOT
Imports Microsoft.SPOT.Hardware
Imports SecretLabs.NETMF.Hardware
'Imports SecretLabs.NETMF.Hardware.NetduinoPlus
Imports SecretLabs.NETMF.Hardware.Netduino
Imports System.IO
Imports System.Text
Imports System.Collections
Imports System.Diagnostics
Imports System.Text.RegularExpressions
Imports System.Math
Module Module1
Sub Main()
Dim buf() As Byte
Dim sing As Single
Dim svalue As Single = 44411.5625
buf = SingleToFourByte(svalue)
sing = FourByteToSingle(buf)
Debug.Print("value - sing = " & (svalue - sing).ToString) '--> 0
End Sub
End Module
Public Function FourByteToSingle(ByVal ByteArray() As Byte) As Single
Dim bin As String = String.Empty
Dim denormalized As Boolean = False
Dim exp, start, coeff As Integer
Dim mantissa As String
Dim sum As Double
Dim TwoPow As Integer = 1
Dim mult As Double = 1
'Convert 4 byte array to binary in reverse order
'(assumes given array came from a 32bit little-endian integer)
'--------------------------------------------------------------
For i As Integer = ByteArray.Length - 1 To 0 Step -1
bin &= IntToBin(ByteArray(i))
Next
'Split apart the binary string. Assumes IEEE 754 single format
'-------------------------------------------------------------
Dim sign As Integer = If(bin.Chars(0) = "1", -1, 1) 'leading bit
Dim expt As Integer = CInt(BinToInt(bin.Substring(1, 8))) 'biased exponent
Dim fraction As String = bin.Substring(9) 'fractional part
Dim TempFraction As Integer = CInt(BinToInt(fraction)) 'integer for testing
'Test for special cases (zero, denormalized, +/-infinity, NaN)
'a good reference for thes cases: http://steve.hollasch.net/cgindex/coding/ieeefloat.html
'----------------------------------------------------------------------------------------
If (expt = 0 And TempFraction = 0) Then Return 0
If (expt = 0 And TempFraction <> 0) Then denormalized = True
If (expt = 255 And TempFraction = 0) Then Return CSng(If(sign = 1, 1 / 0, -1 / 0))
If (expt = 255 And TempFraction <> 0) Then Return 0 / 0
If (denormalized) Then
exp = -126
mantissa = fraction
start = 0
sum = 0
Else
exp = expt - 127
mantissa = "1" & fraction
start = 1
sum = 1 'implied bit
End If
'Convert mantissa to single using double arithmetic to keep full precision
'-------------------------------------------------------------------------
For i As Integer = start To mantissa.Length - 1
TwoPow = 2 * TwoPow
coeff = If(mantissa.Chars(i) = "0", 0, 1)
If (coeff = 0) Then Continue For
sum = sum + 1.0 / TwoPow
Next
'scale the power of 2: 2^exp --> [(2^exp)*(10^-pow10)]*(10^pow10)
'----------------------------------------------------------------
'Constant to scale away exponent power of 2
'log(2)/log(10) = 0.30102999566398119521373889472449
'reqd power of 10 = (power of 2)*(log(2)/log(10))
Dim ReqPowerOf10Const As Double = 0.3010299956639812
Dim Pow10 As Integer = CInt(exp * ReqPowerOf10Const)
Dim Pow2 As Integer = exp - Pow10 'reduce the power of 2 exponent [10^pow10 = (2^pow10)*(5^pow10)]
mult = (2 ^ Pow2 / 5 ^ Pow10) * 10 ^ Pow10
Return CSng(sign * sum * mult)
End Function
Public Function SingleToFourByte(ByVal singl As Single) As Byte()
Dim byts(3) As Byte
Dim test As UInt32 = CUInt(singl)
Dim SingnOf As Integer = Sign(singl) ' = -1 if negative
Dim FracPart As Single
Dim IntPart As UInt32 = CUInt(Floor(Abs(singl))) 'integer part
FracPart = CSng(Abs(singl) - CSng(IntPart)) ' fractional part
Dim FracPartBin As String = String.Empty
Dim IntPartBin As String = String.Empty
FracPartBin = DecFracToBin(FracPart)
IntPartBin = DecIntToBin(IntPart)
'Normalize
Dim BinExpt As Integer = IntPartBin.Length - 1 'Highest bit set -1
Dim Exponent As UInteger = CUInt(BinExpt + 127) ' Biased exponent
Dim BiasedExpt As String = DecIntToBin(Exponent)
'Remove most significant bit
IntPartBin = IntPartBin.TrimStart({"1"c})
'concatenate the mantissa and pad to 23 bits if necesary
Dim Mantissa As String = IntPartBin & FracPartBin
Dim LenMant As Integer = Mantissa.Length
Dim Pad As String = String.Empty
Do Until (LenMant = 23)
Mantissa = Mantissa & "0"
LenMant = Mantissa.Length
Loop
Dim IEEE754 As String = If((SingnOf = -1), "1", "0") & BiasedExpt & Mantissa
Dim LenIEEE As Integer = IEEE754.Length
Utility.InsertValueIntoArray(byts, 0, 4, BinToInt(IEEE754))
Dim k As Integer
Dim substr As String = String.Empty
Return byts
End Function
Function IntToBin(ByVal byt As Byte) As String
'Convert a byte to a binary string
Dim temp As Byte = byt
Dim binval As String = String.Empty
Dim count As Integer = 0
Do
binval = CStr(temp Mod 2) & binval
temp = CByte(temp \ 2)
count += 1
Loop Until count = 8 'pad leading zeros
Return binval
End Function
Public Function BinToInt(bin As String) As UInteger
'Horner's method to evaluate polynomial
'01110110 msb, msb-1, ... 0 (e.g. msb to lsb, left to right)
Dim len As Integer = bin.Length
Dim temp As UInteger = CUInt(If(bin.Chars(0) = "0", 0, 1))
For i As Integer = 1 To len - 1
temp = CUInt(temp * 2 + If(bin.Chars(i) = "0", 0, 1))
Next
Return temp
End Function
Public Function DecFracToBin(frac As Single) As String
Dim BinFrac As String = String.Empty
Dim temp As Single
Dim carry As Integer
While frac <> 0
temp = frac * 2
carry = CInt(Floor(temp))
BinFrac = CStr(carry) & BinFrac
frac = temp - carry
End While
Return BinFrac
End Function
Function DecIntToBin(ByVal Intgr As UInteger) As String
Dim temp As UInteger = Intgr
Dim binval As String = String.Empty
Dim count As Integer = 0
Do
binval = CStr(temp Mod 2) & binval
temp = CUInt(temp \ 2)
count += 1
Loop Until (temp = 0)
Return binval
End Function