Qwe*_*tie 10 .net floating-point bit-manipulation
我想在C#中操纵浮点数的按位表示.BinaryWriter和BinaryReader这样做:
public virtual unsafe void Write(double value)
{
ulong num = *((ulong*) &value);
...
}
public virtual unsafe double ReadDouble()
{
...
ulong num3 = ...;
return *((double*) &num3);
}
Run Code Online (Sandbox Code Playgroud)
有没有办法在没有不安全代码的情况下执行此操作,并且没有实际使用BinaryWriter和BinaryReader的开销?
另一种方法是使用具有显式布局的自定义结构,该结构定义a long
和a double
偏移0.这相当于union
C中的a .
像这样的东西:
using System.Runtime.InteropServices;
[StructLayout(LayoutKind.Explicit)]
struct DoubleLongUnion
{
[FieldOffset(0)]
public long Long;
[FieldOffset(0)]
public double Double;
}
Run Code Online (Sandbox Code Playgroud)
然后用这个:
var union = new DoubleLongUnion();
union.Double = 1.234d;
var longBytes = union.Long;
Run Code Online (Sandbox Code Playgroud)
这将避免任何不安全的代码,并且当您在堆栈上执行转换时也应该执行得非常快.
我没有尝试/编译这个,但我认为它应该工作:)
编辑
我刚试过这个并且它有效.以上值longBytes
是4608236261112822104.
其他一些价值观:
0d -> 0L
double.NaN -> -2251799813685248L
double.MinValue -> -4503599627370497L
double.MaxValue -> 9218868437227405311L
Run Code Online (Sandbox Code Playgroud)
这是一个做你想要的方法:
public static long DoubleToLong(double d)
{
return new DoubleLongUnion { Double = d }.Long;
}
Run Code Online (Sandbox Code Playgroud)
你可以使用byte[] BitConverter.GetBytes(double)
和long BitConverter.ToInt64(byte[],int)
(传递0作为起始索引),但在内部 IIRC这些使用不安全的代码,加上数组的开销.选择你的毒药......
你们是不是要完全避免不安全的代码,或者你只是想在这些具体方法的替代BinaryReader
和BinaryWriter
?
您可以使用BitConverter.DoubleToInt64Bits
and BitConverter.Int64BitsToDouble
,它们旨在完全满足您的需要,尽管我认为它们在幕后使用与BinaryReader
/BinaryWriter
方法相同的不安全转换。
归档时间: |
|
查看次数: |
2529 次 |
最近记录: |