BigEndianBitConverter in Silverlight?
-
20-08-2019 - |
Question
I'm trying to use the MiscUtil.Conversion utility in Silverlight. http://www.yoda.arachsys.com/csharp/miscutil/
When I try to compile it, I get an error saying Silverlight's BitConverter class does not have these two methods:
DoubleToInt64Bits Int64BitsToDouble
Well, I opened up Reflector and found them in mscorlib:
public unsafe long DoubleToInt64Bits(double value)
{
return *(((long*)&value));
}
public unsafe double Int64BitsToDouble(long value)
{
return *(((double*) &value));
}
But the problem with that is that Silverlight does not allow unsafe code. In the project properties menu there's a empty checkbox next to "allow unsafe code", but you cannot change the value.
How can I do this in Silverlight?
Solution
Have a look at BitConverter.ToDouble(byte[], int)
and BitConverter.GetBytes(double)
. If they exist in Silverlight, they may well be good enough. I'm going to investigate this for Protocol Buffers anyway - if I find a good solution, I'll port it back to MiscUtil.
OTHER TIPS
I don't know if this will work in Silverlight or not, but it does work in a Console application, and it doesn't require unsafe code.
If you can get your double values into a byte array, you can swap the bytes in the byte array to change endian-ness. The process can also be reversed, changing the byte array back into a double.
The code that follows illustrates how to convert between double and byte array, using System.InteropServices. The Main method returns two values in the console: 8 and 3.14159. The 8 indicates that a byte array of 8 bytes was successfully created from the double, and 3.14159 indicates that the double was correctly extracted from the byte array.
using System;
using System.IO;
using System.Text;
using System.Runtime.InteropServices;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
double d = 3.14159d;
byte[] b = ToByteArray(d);
Console.WriteLine(b.Length);
Console.ReadLine();
double n = FrpmByteArray(b);
Console.WriteLine(n.ToString());
Console.ReadLine();
}
public static byte[] ToByteArray(object anything)
{
int structsize = Marshal.SizeOf(anything);
IntPtr buffer = Marshal.AllocHGlobal(structsize);
Marshal.StructureToPtr(anything, buffer, false);
byte[] streamdatas = new byte[structsize];
Marshal.Copy(buffer, streamdatas, 0, structsize);
Marshal.FreeHGlobal(buffer);
return streamdatas;
}
public static double FromByteArray(byte[] b)
{
GCHandle handle = GCHandle.Alloc(b, GCHandleType.Pinned);
double d = (double)Marshal.PtrToStructure(
handle.AddrOfPinnedObject(),
typeof(double));
handle.Free();
return d;
}
}
}