开发者

How to get the bits of a "double" as a "long"

开发者 https://www.devze.com 2023-01-31 08:44 出处:网络
I would like to manipulate the bitwise representation of floating-point numbers in C#. BinaryWriter and BinaryReader do it this way:

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

0

精彩评论

暂无评论...
验证码 换一张
取 消