将浮点/双精度/十进制转换为C#中的(u)int,(u)long,无需内存分配

将浮点/双精度/十进制转换为C#中的(u)int,(u)long,无需内存分配,c#,networking,type-conversion,C#,Networking,Type Conversion,我正在为我的游戏开发c#networking解决方案,我在序列化floats、doubles和decimals时遇到问题 我的第一次尝试-位转换器类。但每次我使用该类时,都会创建一个新的byte[]数组,这对于我的网络解决方案(例如,播放器位置同步)来说可能是杀伤力过大 总而言之,我的期望是: 在不分配内存的情况下,可以将floats、doubles和decimals转换为(u)int,(u)long 可以从服务器读取(u)int和(u)long并将转换回原始类型(仍然不分配额外内存) 编辑

我正在为我的游戏开发c#networking解决方案,我在序列化
float
s、
double
s和
decimal
s时遇到问题

我的第一次尝试-
位转换器
类。但每次我使用该类时,都会创建一个新的byte[]数组,这对于我的网络解决方案(例如,播放器位置同步)来说可能是杀伤力过大

总而言之,我的期望是:

  • 在不分配内存的情况下,可以将
    float
    s、
    double
    s和
    decimal
    s转换为(u)int,(u)long
  • 可以从服务器读取(u)int和(u)long并将转换回原始类型(仍然不分配额外内存)
编辑1

这是我在NetworkWriter方法中用于存储要发送的字节的方法:

public void WriteByte(字节值)
{
缓冲区[_position++]=值;
}
这些是我对NetworkWriter的扩展:

public static void WriteUInt(this NetworkWriter writer, uint value)
        {
            writer.WriteByte((byte) value);
            writer.WriteByte((byte) (value >> 8));
            writer.WriteByte((byte) (value >> 16));
            writer.WriteByte((byte) (value >> 24));
        }
这就是我想要将4字节浮点转换为4字节(u)int,这样我就可以将结果int传递给Write(u)int序列化程序

我还没有完成NetworkReader,所以我无法向您显示确切的代码,但它将还原Write方法

我预计会有很多浮点/双精度运算,因为:

  • Vector3(保持玩家位置的职业)是一组3个浮点数
  • 延迟测量将发送/接收双倍时间
  • 四元数(保持玩家旋转的类)也是由4个浮点数组成的
这就是为什么我想尽量减少浮点/双精度/十进制的内存分配

编辑2

重要提示:我知道什么时候需要float、double等,让我快速对阅读器进行伪编码:

static float ReadFloat():
- Get 4 int bytes from buffer
- Construct float from those
有很多选择:

  • BitConverter
    具有类似于
    Int32BitsToSingle(Int32)
    (from和to,32位和64位)的方法,该方法在原语之间执行按位强制;从那里你可以得到无符号的琐碎
  • BinaryPrimitives
    为许多在span上工作的原语提供了读写方法;跨度可以在堆栈上进行零分配(或者更好:可以在输出缓冲区中)
  • 您自己的
    不安全
    代码;获取本地/参数/字段/内部指针的地址,并在取消引用之前强制该指针
  • Unsafe
    类型(尤其是
    As
    方法)允许从
    ref
    在相同大小的原语之间进行直接强制(与
    Unsafe
    选项类似,但是预写的,并使用IL避免非托管指针)
  • MemoryMarshal
    类型(尤其是
    Cast
    方法)允许在类型跨度上进行相同的直接转换,包括在不同大小的类型之间进行转换;特别是,这允许您强制转换任何不包含引用的基元:到
    Span

你只需要施放。Bitconvert仅在必须使用字节数组时使用。你有一个数字,只是转换成一个不同的数字。将浮点数转换为int或long会降低结果的准确性。您还可以使用Math.Abs(float).BitConverter有一个
Int64BitsToDouble
及其计数器部分,它不创建字节数组。向我们展示您的输入和输出。另外:你确定你的网络延迟已经很低了,以至于你真的会注意到这些小的分配所需要的时间/内存吗?你预计会有多少?只是铸造正在失去精度。我试过了。和@rene-我正在编辑问题RN,然后解释你期望如何从一个小数变为一个长或多个长,因为你需要两个这样的值才能不丢失精度。是的,小数可能会变为两个长值。基本上,这是我的问题-如何将float/double/dec值转换为易于序列化的int、long和2 long。