将浮点/双精度/十进制转换为C#中的(u)int,(u)long,无需内存分配
我正在为我的游戏开发c#networking解决方案,我在序列化将浮点/双精度/十进制转换为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并将转换回原始类型(仍然不分配额外内存) 编辑
float
s、double
s和decimal
s时遇到问题
我的第一次尝试-位转换器
类。但每次我使用该类时,都会创建一个新的byte[]数组,这对于我的网络解决方案(例如,播放器位置同步)来说可能是杀伤力过大
总而言之,我的期望是:
- 在不分配内存的情况下,可以将
s、float
s和double
s转换为(u)int,(u)longdecimal
- 可以从服务器读取(u)int和(u)long并将转换回原始类型(仍然不分配额外内存)
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个浮点数组成的
static float ReadFloat():
- Get 4 int bytes from buffer
- Construct float from those
有很多选择:
具有类似于BitConverter
(from和to,32位和64位)的方法,该方法在原语之间执行按位强制;从那里你可以得到无符号的琐碎Int32BitsToSingle(Int32)
为许多在span上工作的原语提供了读写方法;跨度可以在堆栈上进行零分配(或者更好:可以在输出缓冲区中)BinaryPrimitives
- 您自己的
代码;获取本地/参数/字段/内部指针的地址,并在取消引用之前强制该指针不安全
类型(尤其是Unsafe
方法)允许从As
在相同大小的原语之间进行直接强制(与ref
选项类似,但是预写的,并使用IL避免非托管指针)Unsafe
类型(尤其是MemoryMarshal
方法)允许在类型跨度上进行相同的直接转换,包括在不同大小的类型之间进行转换;特别是,这允许您强制转换任何不包含引用的基元:到Cast
Span
Int64BitsToDouble
及其计数器部分,它不创建字节数组。向我们展示您的输入和输出。另外:你确定你的网络延迟已经很低了,以至于你真的会注意到这些小的分配所需要的时间/内存吗?你预计会有多少?只是铸造正在失去精度。我试过了。和@rene-我正在编辑问题RN,然后解释你期望如何从一个小数变为一个长或多个长,因为你需要两个这样的值才能不丢失精度。是的,小数可能会变为两个长值。基本上,这是我的问题-如何将float/double/dec值转换为易于序列化的int、long和2 long。