How to get the bits of a "double" as a "long"
I would like to manipulate the bitwise representation of floating-point numbers in C#. BinaryWriter and BinaryReader do it this way:
public virtual unsafe voi开发者_如何学JAVAd Write(double value)
{
ulong num = *((ulong*) &value);
...
}
public virtual unsafe double ReadDouble()
{
...
ulong num3 = ...;
return *((double*) &num3);
}
Is there a way to do this without unsafe code, and without the overhead of actually using BinaryWriter and BinaryReader?
Another way is to use a custom struct with explicit layout that defines both a long
and a double
at offset 0. This is equivalent to a union
in C.
Something like this:
using System.Runtime.InteropServices;
[StructLayout(LayoutKind.Explicit)]
struct DoubleLongUnion
{
[FieldOffset(0)]
public long Long;
[FieldOffset(0)]
public double Double;
}
Then use this:
var union = new DoubleLongUnion();
union.Double = 1.234d;
var longBytes = union.Long;
This will avoid any unsafe code and should perform pretty fast too as you perform the conversion on the stack.
I haven't tried/compiled this but I reckon it should work :)
EDIT
I just tried this and it works. The value of longBytes
above is 4608236261112822104.
Some other values:
0d -> 0L
double.NaN -> -2251799813685248L
double.MinValue -> -4503599627370497L
double.MaxValue -> 9218868437227405311L
Here's a method that does what you want:
public static long DoubleToLong(double d)
{
return new DoubleLongUnion { Double = d }.Long;
}
Are you trying to avoid unsafe code altogether, or do you just want an alternative to those specific methods on BinaryReader
and BinaryWriter
?
You could use BitConverter.DoubleToInt64Bits
and BitConverter.Int64BitsToDouble
, which are designed to do exactly what you need, although I think they use the same unsafe conversion behind-the-scenes as the BinaryReader
/BinaryWriter
methods.
You can use byte[] BitConverter.GetBytes(double)
and long BitConverter.ToInt64(byte[],int)
(passing 0 as the start-index), but internally IIRC these use unsafe code, plus have the overhead of an array. Pick your poison...
精彩评论