Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/amazon-web-services/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167
Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116
Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180
Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181 C# 将BigInteger转换为十进制(以10为基数)字符串的最快方法?
迄今为止的答案_C#_Tostring_Biginteger - Fatal编程技术网
C# 将BigInteger转换为十进制(以10为基数)字符串的最快方法?
迄今为止的答案,c#,tostring,biginteger,C#,Tostring,Biginteger,下面是代码分解
//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
下面是代码分解
//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
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);
////Usage: string bigIntBase64 = bigIntVar.ToBase64String();
public static string ToBase64String(this BigInteger source)
{
var bigIntBytes = source.ToByteArray().Reverse().ToArray();
return Convert.ToBase64String(bigIntBytes);
}
//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);
}
var powersOfTen=new List<BigInteger>();
powersOfTen.Add(1);
for(BigInteger i=10;i<n;i=i*i)
powersOfTen.Add(i);
string ToString(BigInteger n, int m)
{
if(m==0)
return n.ToString();
quotient = DivRem(n,powersOfTen[m], remainder)
return ToString(quotient, m-1)+ToString(remainder, m-1)
}
List<int> multiply(List<int> f1, int f2)
{
int carry=0;
for(int i=0;i<f1.Count;i++)
{
var product=(Int64)f1[i]*(Int64)f2;
carry=product/1000000000;
result.Add(product%1000000000);
}
if(carry!=0)
result.Add(carry);
}
Stats on my quad core P7:
Generating a 500k digit random number using power and multiply: 5 seconds
Dividing that big number by anything just once: 11 seconds
ToString(): 22 seconds
ToQuickString: 18 seconds
ToStringMT: 12.9 seconds
public static class BigIntExtensions
{
private static List<BigInteger> powersOfTen;
// Must be called before ToStringMt()
public static void InitPowersOfTen(BigInteger n)
{
powersOfTen = new List<BigInteger>();
powersOfTen.Add(1);
for (BigInteger i = 10; i < n; i *= i)
powersOfTen.Add(i);
}
public static string ToStringMT(this BigInteger n)
{
// compute the index into the powersOfTen table for the given parameter. This is very fast.
var m = (int)Math.Ceiling(Math.Log(BigInteger.Log10(n), 2));
BigInteger r1;
// the largest amount of execution time happens right here:
BigInteger q1 = BigInteger.DivRem(n, BigIntExtensions.powersOfTen[m], out r1);
// split the remaining work across 4 threads - 3 new threads plus the current thread
var t1 = Task.Factory.StartNew<string>(() =>
{
BigInteger r1r2;
BigInteger r1q2 = BigInteger.DivRem(r1, BigIntExtensions.powersOfTen[m - 1], out r1r2);
var t2 = Task.Factory.StartNew<string>(() => BuildString(r1r2, m - 2));
return BuildString(r1q2, m - 2) + t2.Result;
});
BigInteger q1r2;
BigInteger q1q2 = BigInteger.DivRem(q1, BigIntExtensions.powersOfTen[m - 1], out q1r2);
var t3 = Task.Factory.StartNew<string>(() => BuildString(q1r2, m - 2));
var sb = new StringBuilder();
sb.Append(BuildString(q1q2, m - 2));
sb.Append(t3.Result);
sb.Append(t1.Result);
return sb.ToString();
}
// same as ToQuickString, but bails out before m == 0 to reduce call overhead.
// BigInteger.ToString() is faster than DivRem for smallish numbers.
private static string BuildString(BigInteger n, int m)
{
if (m <= 8)
return n.ToString();
BigInteger remainder;
BigInteger quotient = BigInteger.DivRem(n, powersOfTen[m], out remainder);
return BuildString(quotient, m - 1) + BuildString(remainder, m - 1);
}
}