Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/271.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 可变精度浮点/双精度值_C#_Serialization_Protobuf Net - Fatal编程技术网

C# 可变精度浮点/双精度值

C# 可变精度浮点/双精度值,c#,serialization,protobuf-net,C#,Serialization,Protobuf Net,我有一个我正在序列化的对象,它包含了很多double和double的结构,我用protobuf-net通过网络发送。问题是,在整个过程中,我不需要所有的精度 例如,我有这样一个例子,外部库返回一个double double Volts=Sampler.GetValue()//伏特值类似于4.35(…) 但我真的只需要两个小数点的精度。将其作为双精度编码需要64位。将其编码为具有2位十进制精度(“4.35”)的字符串实际上可能占用更少的空间。但我还有转换问题要处理 我一直在探索v2选项,但我还没有

我有一个我正在序列化的对象,它包含了很多double和double的结构,我用protobuf-net通过网络发送。问题是,在整个过程中,我不需要所有的精度

例如,我有这样一个例子,外部库返回一个double

double Volts=Sampler.GetValue()//伏特值类似于4.35(…)

但我真的只需要两个小数点的精度。将其作为双精度编码需要64位。将其编码为具有2位十进制精度(“4.35”)的字符串实际上可能占用更少的空间。但我还有转换问题要处理

我一直在探索v2选项,但我还没有看到这样的功能。我可以看出,如果可以将浮点值编码为可变长度的精度,它将节省大量空间

我曾考虑过将其乘以一个整数,然后将其发送到远端,然后将其转换回远端,但据我所知,这需要我对基类对象进行重大更改(我在反序列化过程中使用了merge选项)

有什么想法或聪明的解决办法吗


顺便说一句,protobuf网络的可配置性非常好。感谢您制作了这么好的程序。

将数据序列化为字符串听起来不是个好主意

双精度值已经只有64位了(参见,wire type 1),文本以UTF-8的形式传输,因此即使在简化的4.35示例中,也需要32位进行传输,更不用说在反序列化时将其转换回双精度值,以及在有人查看该代码时的一般维护噩梦


如果您不需要精度,我建议使用浮点,它只使用32位,但在使用这些值及其序列化时保持一致。

将数据序列化为字符串听起来是个坏主意

双精度值已经只有64位了(参见,wire type 1),文本以UTF-8的形式传输,因此即使在简化的4.35示例中,也需要32位进行传输,更不用说在反序列化时将其转换回双精度值,以及在有人查看该代码时的一般维护噩梦

如果您不需要精度,我建议使用浮点,它只使用32位,但在使用这些值及其序列化时保持一致。

继续“可能将它们作为
浮点发送”
讨论,实际上,您可以很容易地做到这一点;例如,如果您当前有:

[ProtoMember(4)]
public double Value {get;set;}
您可以将其更改为:

public double Value {get;set;} // this won't be serialized directly

[Protomember(4)] // but we'll use this private property for the serialization
private float ValueSingle {
    get { return (float)Value; }
    set { Value = value; }
}
它会在背景中为你做垫片。这个特殊的更改也应该与现有数据兼容(虽然从技术上讲它确实更改了.proto模式,但protobuf net是相当宽容的)。这将需要4个字节。还请注意,IEEE754一如既往地适用,因此与protobuf net完全无关无法保证任何特定值(例如4.35)可以准确存储

另一种选择是,如果您想要固定精度,可以使用倍数。例如:

public double Value {get;set;}

[ProtoMember(4)]
public int ValueInt32 {
    get { return (int)Math.Round(100 * Value); }
    set { Value = value/100.0; }
}
您必须进行测试,看看是否与旧数据兼容。。。这是一个更大的变化。在这里,4.35将作为435发送,它将2个字节作为一个“变量”。

进行“可能将它们作为
float
发送”的讨论,实际上,您可以很容易地做到这一点;例如,如果您当前有:

[ProtoMember(4)]
public double Value {get;set;}
您可以将其更改为:

public double Value {get;set;} // this won't be serialized directly

[Protomember(4)] // but we'll use this private property for the serialization
private float ValueSingle {
    get { return (float)Value; }
    set { Value = value; }
}
它会在背景中为你做垫片。这个特殊的更改也应该与现有数据兼容(虽然从技术上讲它确实更改了.proto模式,但protobuf net是相当宽容的)。这将需要4个字节。还请注意,IEEE754一如既往地适用,因此与protobuf net完全无关无法保证任何特定值(例如4.35)可以准确存储

另一种选择是,如果您想要固定精度,可以使用倍数。例如:

public double Value {get;set;}

[ProtoMember(4)]
public int ValueInt32 {
    get { return (int)Math.Round(100 * Value); }
    set { Value = value/100.0; }
}

您必须进行测试,看看是否与旧数据兼容。。。这是一个更大的变化。这里,4.35将作为435发送,它需要2个字节作为一个“变量”。

“将它作为一个双字节进行编码需要64个字节。”-不,它需要64位=8字节。如果你真的关心空间的话,这里有一个“半浮点数”(在这种情况下是指带宽)。谢谢,修复了位/字节的错误。“将其作为双精度编码需要64个字节。”-不,需要64位=8字节。如果你真的关心空间,那么就有“半浮点数”(在这种情况下是带宽)。谢谢,修复了位/字节输入错误。是的,我在考虑ASCII文本。Unicode显然会更糟。我可以使用浮点数并将数据大小减半。我可以到处强制转换,因为所有内容都返回双倍(包括第三方对象)。更改它并在任何地方强制转换可能会涉及到上千行代码。是的,我真的搞砸了位/字节。盯着屏幕看太久了。但我的一般问题仍然存在。浮动可能不值得我更改多少行代码。是的,我想ASCII文本。Unicode显然会更糟。我可以使用浮动并将数据大小减半。我可以在任何地方进行强制转换,因为所有内容都返回双倍(包括第三方对象)。更改它并在任何地方强制转换可能会涉及到上千行代码。是的,我确实搞砸了位/字节。盯着屏幕看的时间太长了。但我的一般问题仍然存在。浮动可能不值得我花费精力更改多少行代码。我实际上只是在挖掘protobuf网络代码以查看about用属性修饰一个double基本上是第二个想法,我可以用
FixedPrecision=2
来修饰一个double,并在序列化/反序列化中处理它。如果失败,我可能会编辑这个命令