How to get the bits of a “double” as a “long”

可紊 提交于 2019-12-05 01:36:16

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.

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;
}

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...

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!