到目前为止的答案
所以这里是代码分解。
//Time: ~7s (linear loop algorithm)
//100,000! (456,574 decimal digits)
BigInteger bigIntVar = computeFactorial(100000);
//The first three here are just for comparison and are not actually Base 10.
bigIntVar.ToBase64String() //Time: 00.001s | Base 64 | Tetrasexagesimal
bigIntVar.ToString("x") //Time: 00.016s | Base 16 | Hexadecimal
bigIntVar.ToBinaryString() //Time: 00.026s | Base 02 | Binary
bigIntVar.ToQuickString() //Time: 11.200s | Base 10 | String Version
bigIntVar.ToQuickString() //Time: 12.500s | Base 10 | StringBuilder Version
bigIntVar.ToString() //Time: 13.300s | Base 10 | Original
原始问题
我在这方面花了很多时间,所以我需要你的帮助。
这是用于计算巨大阶乘的个人项目(例如 100,000!)
这是我的代码:
using (var stream = new StreamWriter(fileName + ".txt", false))
{
stream.WriteLine(header);
var timer = new Stopwatch();
timer.Restart();
//This is the huge BigInteger holding the answer to 100,000!
stream.WriteLine(saveFactorial.Output.ToString());
//Let me be clear: ToString() is directly causing the the 13sec time delay.
//Not the stream.
timer.Stop();
}
time = (timer.ElapsedMilliseconds / 1000.0).ToString() + "s";
MessageBox.Show(time);
100,000!在我的机器上计算大约需要 7 秒(线性循环算法)。
然而,使用此标准 IO 代码需要 13 秒才能保存。
所以换句话说,保存工作比适度计算它需要更长的时间。
所以我想也许我可以使用:
BigInteger.ToByteArray();
尽管它运行得非常快,但我不知道如何将其保存为可读文本。
您可以使用上述方法将二进制字符串写入具有此自制扩展名的文本文件:
ToBinaryString
//Usage: string bigIntBinary = bigIntVar.ToBinaryString();
public static string ToBinaryString(this BigInteger source)
{
//If you lookup the ToByteArray() method...
//It actually stores the bytes in reverse order.
var bigIntBytes = source.ToByteArray().Reverse();
StringBuilder bigIntBinary = new StringBuilder();
foreach (var bigIntByte in bigIntBytes)
{
bigIntBinary.Append(Convert.ToString(bigIntByte, 2).PadLeft(8, '0'));
}
return bigIntBinary.ToString();
}
ToBase64String
////Usage: string bigIntBase64 = bigIntVar.ToBase64String();
public static string ToBase64String(this BigInteger source)
{
var bigIntBytes = source.ToByteArray().Reverse().ToArray();
return Convert.ToBase64String(bigIntBytes);
}
我还尝试了数学方法(mod 10 等...)来获取每个数字,但这需要比 ToString() 多 TON 的时间。
我在这里做错了什么?
这段代码是我根据下面的答案提出的。这比 ToString() 快,但只快了几秒钟。
ToQuickString
//Usage: string bigIntString = bigIntVar.ToQuickString()
public static String ToQuickString(this BigInteger source)
{
powersOfTen = new List<BigInteger>();
powersOfTen.Add(1);
for (BigInteger i = 10; i < source; i *= i)
{
powersOfTen.Add(i);
}
return BuildString(source, powersOfTen.Count - 1).ToString().TrimStart('0');
}
private static List<BigInteger> powersOfTen;
private static string BuildString(BigInteger n, int m)
{
if (m == 0)
return n.ToString();
BigInteger remainder;
BigInteger quotient = BigInteger.DivRem(n, powersOfTen[m], out remainder);
return BuildString(quotient, m - 1) + BuildString(remainder, m - 1);
}