.NET十进制跨平台标准

V.B*_*.B. 1 .net c# decimal

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

我在存储之前将所有数字数据转换为小数,因为当一个小数数组被差分然后压缩时,实际数据的结果 blob 大小比任何算法压缩的浮点 blob 小得多(我的测试显示 c.2x更小的空间)。并且小数不会失去差异的精度。但我不确定我是否可以从 .NET 语言以外的任何其他语言读取这些 blob。

我正在阅读维基页面,但我自己无法回答这个简单的问题。

更新:

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

Dai*_*Dai 5

对于文档System.Decimal类型没有做它使用什么样的内部表示状态(不同于System.SingleSystem.Double使用IEEE-754)。鉴于此,您不能假设任何十进制数的原始二进制状态表示在 .NET Framework 版本之间甚至在运行相同版本的物理机之间是一致的。

我假设你会使用 BinaryWriter.Write(Decimal value)方法。此方法的文档没有对所使用的实际格式做出任何声明。

查看 .NET 参考源代码,我们看到它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 );
Run Code Online (Sandbox Code Playgroud)

这种方法使用 17 个字节来存储一个Decimal实例,无论Decimal类型的内部设计如何,这种方式都可以记录并保证可以正常工作。16 个字节存储实际值,1 个字节存储表示十进制所需的 32 位整数的数量(以防数字从 4 改变)。