.NET十进制跨平台标准 [英] .NET decimal cross-platform standard

查看:39
本文介绍了.NET十进制跨平台标准的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

If I save C# decimal array to a binary blob with a binary writer, will I be able to seamlessly read this blob in Java or Python or R? Do these language have a corresponding data type or is there a cross-platform standard that .NET decimal adheres to?

我在存储之前将所有数值数据转换为十进制,因为当对十进制数组进行扩散然后进行压缩时,对于现实世界数据,所生成的Blob大小要比任何算法所压缩的float Blob小得多(我的测试显示c.少2倍的空间).小数点后的精度也不会降低.但是我不确定是否可以从.NET以外的任何其他语言中读取该Blob.

I am converting all my numeric data to decimals before storing, because when an array of decimals is diffed and then compressed, the resulting blob size is much smaller for real world data than a float blob compressed by any algo (my tests show c.2x less space). And decimals do not lose precision on diffing. But I am not sure if I could read this blobs from any other language other than .NET ones.

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

I am reading the wiki page but cannot answer this simple question myself.

更新:

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

Currently I take an unsafe reference to decimal[] array and cast it to (byte* ) pointer, but this is equivalent to binary writer. The question is about cross-platform decimal interop, not serialization. See my comment in the first answer.

推荐答案

System.Decimal 类型的文档未说明其使用的内部表示形式(不同于 System.Single System.Double ).鉴于此,您不能假定任何十进制数字的原始二进制状态表示形式在.NET Framework版本之间,甚至在运行相同版本的物理计算机之间都将是一致的.

The documentation for the System.Decimal type does not state what internal representation it uses (unlike System.Single and System.Double which use IEEE-754). Given this, you cannot assume that the raw binary state representation of any decimal number will be consistent between .NET Framework versions or even between physical machines running the same version.

我假设您将使用 BinaryWriter.Write(Decimal value)方法.此方法的文档没有使关于使用的实际格式的任何声明.

I assume you'd be using the BinaryWriter.Write(Decimal value) method. The documentation for this method does not make any statement about the actual format being used.

查看.NET参考源代码,我们看到了 BinaryWriter.Write(Decimal)使用内部方法: Decimal.GetBytes(Byte [] buffer)使用未记录的格式,该格式将来可能会更改,或者可能会有所不同机器.

Looking at the .NET Reference source code, we see that BinaryWriter.Write(Decimal) uses an internal method: Decimal.GetBytes(Byte[] buffer) which uses an undocumented format which might change in future or may differ per-machine.

但是! Decimal 类确实提供了一个公共方法 GetBits ,它确实保证了它返回的数据格式,所以我建议您改用它:

However! The Decimal class does provide a public method GetBits which does make guarantees about the format of data it returns, so I suggest you use this instead:

// 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更改).

This approach uses 17 bytes to store a Decimal instance in a way that is documented and guaranteed to work regardless of the internal design of the Decimal type. 16 bytes store the actual value, and 1 byte stores the number of 32-bit integers needed to represent the decimal (in case the number ever changes from 4).

这篇关于.NET十进制跨平台标准的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆