如何重新解释将float转换为int? 是否有非静态转换运算符或用户定义的赋值运算符用于’this’的转换?

1.如何重新解释将浮点数转换为int(或者double到long)?

float f = 2.0f; int i = (int)f; // causes conversion 

我只想将位模式从f复制到i 。 如何才能做到这一点?

2. C#中的隐式和显式运算符使用一个中间对象,因为运算符函数是静态的

 public static implicit operator MyClass(double s) { return new MyClass(s); } .. .. MyClass m = 2.2; // this code uses 'm' and one intermediate object. 

这适用于引用类型,但对于较大的值类型(例如20-30字节),这将导致不必要的数据复制。 我的理解是否正确? 如果是,那么为什么C#没有非静态转换运算符或用户定义的赋值运算符,以便转换/赋值发生在’this’上? 如果是的话,那是怎么做的?

  1. BitConverter类可以检索任何基本类型的字节,然后可以使用它来创建int。 如果您要进行大量转换,则另一个选项是Buffer.BlockCopy 。

     float ff = 2.0f; int ii = BitConverter.ToInt32(BitConverter.GetBytes(ff), 0); float[] ff = new float[...]; int[] ii = new int[ff.Length]; Buffer.BlockCopy(ff, 0, ii, 0, ff.Length * 4); // byte-wise copy of ff into ii 
  2. 没有在C#中没有给出其他选项,但是,我认为虽然你是正确的,因为会有副本,任何足够简单的实现都会完成JIT优化,可能无需复制。

1:BitConverter(作为sixlettervararia)是一个选项; 因为不安全的代码(不需要中间缓冲区):

  float f = 2.0f; int i; // perform unsafe cast (preserving raw binary) unsafe { float* fRef = &f; i = *((int*)fRef); } Console.WriteLine(i); // prove same answer long-hand byte[] raw = BitConverter.GetBytes(f); int j = BitConverter.ToInt32(raw, 0); Console.WriteLine(j); 

2:请注意,您应该限制结构的大小。 我找不到引用它,但数字“16字节”(最大,作为推荐)似乎坚持在我的脑海里。 在此之上,考虑一个不可变的引用类型(类)。

禁止使用不安全的代码 – 这是我所知道的执行重新解释的最快方法:

  [StructLayout(LayoutKind.Explicit)] private struct IntFloat { [FieldOffset(0)] public int IntValue; [FieldOffset(0)] public float FloatValue; } private static float Foo(float x) { var intFloat = new IntFloat { FloatValue = x }; var floatAsInt = intFloat.IntValue; ... 

希望这有助于某人。

这种方法虽然不安全,但却可以作为通用解决方案

 static unsafe TDest ReinterpretCast(TSource source) { var tr = __makeref(source); TDest w = default(TDest); var trw = __makeref(w); *((IntPtr*)&trw) = *((IntPtr*)&tr); return __refvalue(trw, TDest); } 

这应该是最快速,最干净的方法:

 public static class ReinterpretCastExtensions { public static unsafe float AsFloat( this int n ) => *(float*)&n; public static unsafe int AsInt( this float n ) => *(int*)&n; } public static class MainClass { public static void Main( string[] args ) { Console.WriteLine( 1.0f.AsInt() ); Console.WriteLine( 1.AsFloat() ); } }