如何在文件中读/写C#BigIntegers?

时间:2011-07-23 08:00:02

标签: c# serialization biginteger

在我的一个类中,我有一个例程,它读取和写入一个Decimal类型的数组(使用BinaryReader / BinaryWriter的{​​{1}}和ReadDecimal()方法,说:

Write()

BinaryReader inputReader = new BinaryReader(File.OpenRead(BaseFilePath));
for (int x = 0; x < 6; x++) {
    for (int y = 0; y < m_Codes[x].GetLength(0); y++) {
        for (int z = 0; z < m_Codes[x].GetLength(1); z++) {
            m_Codes[x][y, z] = inputReader.ReadDecimal();
        }
    }
}

..如您所见,在设计时只知道第一个维度,其他维度在运行时会有所不同。

在一个完美的世界中,我会用for (int x = 0; x < 6; x++) { for (int y = 0; y < m_Codes[x].GetLength(0); y++) { for (int z = 0; z < m_Codes[x].GetLength(1); z++) { outputWriter.Write(m_Codes[x][y, z]); } } } 替换ReadDecimal()和写作方法类似的东西,但在Stream类中似乎不支持;我猜这是因为BigInteger可以是任何长度。

关于我能想到的最好的事情是将BigInteger“手动编码”,将其转换为ReadBigInteger()数组,然后写入该数组的长度,然后在数组本身中写入每个字节(和反过来阅读它)

两个问题:

1)这是一种更好的方式吗?

2)我主要是出于提高绩效的愿望; boes BigInteger甚至比Decimal表现得更好,如果有的话呢?

2 个答案:

答案 0 :(得分:4)

有一个相当简单的方法:在序列化时调用BigDecimal.ToByteArray,在反序列化时调用BigDecimal(byte[])构造函数。不可否认,最终会复制数据,但我仍然期望它的速度相当快。

您还关注什么:序列化性能或算术性能?

至于BigIntegerdecimal之间的任何速度差异 - 您应该针对您实际想要执行的操作测试它,意识到它们的行为会有所不同(例如,将3除以2显然会给出每种类型的答案都不同。)

答案 1 :(得分:2)

您可以转换为字符串(BigInteger.ToSting()),然后编写该字符串(因为BinaryReaderBinaryWriter直接支持字符串,这样可以避免自己需要进行任何编码/解码

然后使用BigInteger.Parse将其转换回来。

为了解决这个问题:我认为你需要衡量你感兴趣的案例。

当相对较小的值(比如abs(值)&lt; 2 128 )时,我期望 BigInteger的表现在几个订单内long性能的大小(即不超过约500倍)。但是当BigInteger实例变大时,操作将花费更长时间(需要操作更多位)。另一方面,decimal应该在所有比例下具有相当一致的性能,但对于它们范围交叉点中的数字,它可能比long慢得多(decimal要复杂得多表示:比例因子和通过计算保留实际有效数字;但没有直觉这种复杂性的影响)。

请记住:BigDecimal确切 - 它永远不会圆; decimal是近似值 - 数据可以从最终落下并丢弃。任何一个业务问题似乎都不太可能支持。