Convert half float to int 16 to write it in a file
Hi i have a problem i am programming with visual basic, and i believe that is not possible to declare half float variables so for read an uv data from a file represented in half floats i use a dll, but now i need to do the inverse, i have to convert float numbers to half float and this to int16 because this is the only way that i know to write a half float into a file in visual basic
Quote:Original post by ZahlmanI think he's saying he's got a file with a bunch of half-floats (like float16) that he's gotta read in Visual Basic. To do that, he made a DLL that he could call from Visual Basic that would read the half float (and maybe convert it to a regular-float that he would pass back to his Visual Basic program, I'm guessing?). But now he's got a bunch of floats in his Visual Basic code that he needs to write to the file, but they have to be written as half-floats, not regular-floats, and, AFAIK, Visual Basic doesn't have any built in functionality to let you do that.
... What?
Please try to organize what you're saying a little better.
My suggestion? You've already got a DLL that will read the half-floats and give them to your Visual Basic program. Why not add to that DLL the functionality to pass a float to a function in the DLL, and the DLL converts it to a half-float and then writes it to the file? Though you'll have to watch out for endianness if you're doing this.
Quote:Original post by MikeTacularQuote:Original post by ZahlmanI think he's saying he's got a file with a bunch of half-floats (like float16) that he's gotta read in Visual Basic. To do that, he made a DLL that he could call from Visual Basic that would read the half float (and maybe convert it to a regular-float that he would pass back to his Visual Basic program, I'm guessing?). But now he's got a bunch of floats in his Visual Basic code that he needs to write to the file, but they have to be written as half-floats, not regular-floats, and, AFAIK, Visual Basic doesn't have any built in functionality to let you do that.
... What?
Please try to organize what you're saying a little better.
My suggestion? You've already got a DLL that will read the half-floats and give them to your Visual Basic program. Why not add to that DLL the functionality to pass a float to a function in the DLL, and the DLL converts it to a half-float and then writes it to the file? Though you'll have to watch out for endianness if you're doing this.
That´s exactly what i mean, the problem is that i don´t know how to build a dll for this, because i don´t understand half float standard.the dll that i use to read the half float numbers was build by a friend using a free code that was already created.
Can you get the source code to the original DLL? If so, it should be fairly easy to see how it does the conversions, and mimic this to do what you need.
here is the code of the original dll:
[Edited by - ApochPiQ on June 8, 2009 11:29:36 AM]
Public Class Class1 ' Methods Public Function inttohalf(ByVal h As Short) As Single Dim hh As Integer If (h = 0) Then Return 0! End If Dim s As Integer = ((h >> 15) And 1) Dim e As Integer = ((h >> 10) And &H1F) Dim f As Integer = (h And &H3FF) Select Case e Case 0 If (f = 0) Then hh = (s << &H1F) Else hh = (f And &H400) Do While (hh = 0) f = (f << 1) e -= 1 e += 1 f = (f And -1025) Loop End If Exit Select Case &H1F If (f = 0) Then hh = ((s << &H1F) Or &H7F800000) Else hh = (((s << &H1F) Or &H7F800000) Or (f << 13)) End If Exit Select End Select e = (e + &H70) f = (f << 13) hh = (((s << &H1F) Or (e << &H17)) Or f) Return BitConverter.ToSingle(BitConverter.GetBytes(hh), 0) End FunctionEnd Class
[Edited by - ApochPiQ on June 8, 2009 11:29:36 AM]
Here is a simple answer to your question in C#. If you are using a .NET version of Visual Basic, the library calls should be similar. Not sure of VB syntax, sorry.
This converts the value of floatValue to a UInt16 with identical bits to a "half-float." Does not take care of any special cases or Endianness, so it will need some revising to be robust, but it is a start.
float floatValue = -0.75F; byte[] bytes = BitConverter.GetBytes((double)floatValue); ulong bits = BitConverter.ToUInt64(bytes, 0); // Extract exponent from IEEE double ulong exponent = bits & 0x7ff0000000000000L; // Extract mantissa from IEEE double ulong mantissa = bits & 0x000fffffffffffffL; // Extract sign ulong sign = bits & 0x8000000000000000L; // Determine the offset from the bias of the exponent int placement = (int)((exponent >> 52) - 1023); // Check to see if offset from bias is allowable in half float if (placement > 15 || placement < -14) { throw new ArgumentOutOfRangeException("Exponent portion of float value is too large to store in half-float."); } // Create 16 bit masks, truncating precision of mantissa UInt16 exponentBits = (UInt16)((15 + placement) << 10); UInt16 mantissaBits = (UInt16)(mantissa >> 42); UInt16 signBits = (UInt16)(sign >> 48); // Logical OR all together UInt16 halfFloatBits = (UInt16)(exponentBits | mantissaBits | signBits);
This converts the value of floatValue to a UInt16 with identical bits to a "half-float." Does not take care of any special cases or Endianness, so it will need some revising to be robust, but it is a start.
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement