.NET十进制跨平台标准

时间:2015-01-22 01:53:35

标签: c# .net decimal

如果我使用二进制编写器将C#十进制数组保存到二进制blob,我是否能够在Java或Python或R中无缝读取此blob?这些语言是否具有相应的数据类型,或者是否存在.NET十进制所遵循的跨平台标准?

我在存储之前将所有数字数据转换为小数,因为当小数组数组被扩散然后压缩时,生成的blob大小比任何算法压缩的float blob要小得多(我的测试显示) c.2x较小的空间)。并且小数在变差时不会失去精确度。但是我不确定我是否可以从除.NET之外的任何其他语言中读取这些blob。

我正在阅读the wiki page,但我自己无法回答这个简单的问题。

更新

目前我对decimal[]数组进行了不安全的引用并将其转换为(byte* )指针,但这相当于二进制编写器。问题是关于跨平台十进制互操作,而不是序列化。在第一个答案中查看我的评论。

1 个答案:

答案 0 :(得分:4)

System.Decimal类型的文档未说明它使用的内部表示形式(与使用IEEE-754的System.SingleSystem.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变化)。

相关问题