【发布时间】:2010-02-02 19:47:04
【问题描述】:
因此,我正在尝试改进 .net 4 的 BigInteger 类提供的一些操作,因为这些操作看起来是二次的。我做了一个粗略的 Karatsuba 实现,但它仍然比我预期的要慢。
主要问题似乎是 BigInteger 没有提供简单的方法来计算位数,因此我必须使用 BigInteger.Log(..., 2)。根据 Visual Studio,大约 80-90% 的时间都花在计算对数上。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Numerics;
namespace Test
{
class Program
{
static BigInteger Karatsuba(BigInteger x, BigInteger y)
{
int n = (int)Math.Max(BigInteger.Log(x, 2), BigInteger.Log(y, 2));
if (n <= 10000) return x * y;
n = ((n+1) / 2);
BigInteger b = x >> n;
BigInteger a = x - (b << n);
BigInteger d = y >> n;
BigInteger c = y - (d << n);
BigInteger ac = Karatsuba(a, c);
BigInteger bd = Karatsuba(b, d);
BigInteger abcd = Karatsuba(a+b, c+d);
return ac + ((abcd - ac - bd) << n) + (bd << (2 * n));
}
static void Main(string[] args)
{
BigInteger x = BigInteger.One << 500000 - 1;
BigInteger y = BigInteger.One << 600000 + 1;
BigInteger z = 0, q;
Console.WriteLine("Working...");
DateTime t;
// Test standard multiplication
t = DateTime.Now;
z = x * y;
Console.WriteLine(DateTime.Now - t);
// Test Karatsuba multiplication
t = DateTime.Now;
q = Karatsuba(x, y);
Console.WriteLine(DateTime.Now - t);
// Check they're equal
Console.WriteLine(z == q);
Console.Read();
}
}
}
那么,我该怎么做才能加快速度呢?
【问题讨论】:
-
您能否介绍一下 Karatsuba 是什么?
-
我不确定这是否会有所帮助,但也许您可以以某种方式将其转换为 BitArray 以便您可以计算位数。
-
@aaronls:这要快得多,谢谢。
-
<<的优先级低于+/-
标签: c# biginteger