如果我使用二进制编写器将C#十进制数组保存到二进制blob,我是否能够在Java或Python或R中无缝读取此blob?这些语言是否具有相应的数据类型,或者是否存在.NET十进制所遵循的跨平台标准?
我在存储之前将所有数字数据转换为小数,因为当小数组数组被扩散然后压缩时,生成的blob大小比任何算法压缩的float blob要小得多(我的测试显示) c.2x较小的空间)。并且小数在变差时不会失去精确度。但是我不确定我是否可以从除.NET之外的任何其他语言中读取这些blob。
我正在阅读the wiki page,但我自己无法回答这个简单的问题。
更新
目前我对decimal[]
数组进行了不安全的引用并将其转换为(byte* )
指针,但这相当于二进制编写器。问题是关于跨平台十进制互操作,而不是序列化。在第一个答案中查看我的评论。
答案 0 :(得分:4)
System.Decimal
类型的文档未说明它使用的内部表示形式(与使用IEEE-754的System.Single
和System.Double
不同)。鉴于此,您不能假设任何十进制数的原始二进制状态表示在.NET Framework版本之间或甚至在运行相同版本的物理机之间是一致的。
我假设你正在使用BinaryWriter.Write(Decimal value)
方法。 The documentation for this method没有对正在使用的实际格式做出任何陈述。
Looking at the .NET Reference source code,我们看到BinaryWriter.Write(Decimal)
使用了一种内部方法:Decimal.GetBytes(Byte[] buffer)
,它使用的是未记录的格式,可能会在将来发生变化,也可能因机器而异。
然而! Decimal
类确实提供了一个公共方法GetBits
,它确实保证了它返回的数据格式,所以我建议你改用它:
// Writing
Int32[] bits = myDecimal.GetBits();
binaryWriter.Write( (byte)bits.Length );
foreach(Int32 component in bits) binaryWriter.Write( component );
// Reading
byte count = binaryReader.ReadByte();
Int32[] bits = new Int32[ count ];
for(Int32 i = 0; i < bits.Count; i++ ) {
bits[i] = binaryReader.ReadInt32();
}
Decimal value = new Decimal( bits );
此方法使用17个字节以记录的方式存储Decimal
实例,并保证无论Decimal
类型的内部设计如何都能正常工作。 16个字节存储实际值,1个字节存储表示小数所需的32位整数数(如果数字从4变化)。