- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
作为我的 BigDecimal 库的一部分,我需要计算任何给定非负整数的阶乘。所以我使用 .Net 4.0 的 System.Numerics.BigInteger
来存储大量数据。这是我正在使用的功能:
private BigInteger Factorial(BigInteger x)
{
BigInteger res = x;
x--;
while (x > 1)
{
res *= x;
x--;
}
return res;
}
它正在运行但未优化。现在我想使用并行计算,所以这是我尝试过的:(我没有并行编程的经验)
public BigInteger Factorial(long x)
{
BigInteger res = 1;
ParallelLoopResult r = Parallel.For(2L, (x + 1), i =>
res *= i
);
return res;
}
奇怪的问题是,上面的函数对于像 5 这样的小数字非常有效!但不适用于 1000 这样的大数字!并且每次都返回完全不同的结果。所以我意识到它不是线程安全的,问题出在变量 res
上。我想知道正确的实现是什么?
如果我可以使用 BigInteger 而不是 long 变量 x
会更好。
最佳答案
您需要确保您的并行进程不共享任何状态。
例如,在阶乘的情况下,我会执行以下操作:
这在某种程度上是一个简化的 Map-Reduce 。
问题在于将一组数字相乘。将此集合划分为子集的一种方法是使用 N
并行 for 循环,其中每个循环都从值 i
(其中 0 < i <= N
)开始,步长为 N
(和 N
= DOP
)。
这是执行此操作的代码:
/// <summary>
/// The max number of parallel tasks
/// </summary>
static readonly int DegreeOfParallelism = Environment.ProcessorCount;
public BigInteger Factorial(long x)
{
// Make as many parallel tasks as our DOP
// And make them operate on separate subsets of data
var parallelTasks =
Enumerable.Range(1, DegreeOfParallelism)
.Select(i => Task.Factory.StartNew(() => Multiply(x, i),
TaskCreationOptions.LongRunning))
.ToArray();
// after all tasks are done...
Task.WaitAll(parallelTasks);
// ... take the partial results and multiply them together
BigInteger finalResult = 1;
foreach (var partialResult in parallelTasks.Select(t => t.Result))
{
finalResult *= partialResult;
}
return finalResult;
}
/// <summary>
/// Multiplies all the integers up to upperBound, with a step equal to DOP
/// starting from a different int
/// </summary>
/// <param name="upperBoud"></param>
/// <param name="startFrom"></param>
/// <returns></returns>
public BigInteger Multiply(long upperBound, int startFrom)
{
BigInteger result = 1;
for (var i = startFrom; i <= upperBound; i += DegreeOfParallelism)
result *= i;
return result;
}
在我的机器上,这会在大约 30 秒内计算出 100000!
,结果是 what Wolfram Alpha says it should be。
再运行几次测试后,我发现了一些出乎我意料的事情:将 100000!
结果打印到控制台需要大约 18 秒(结果有 456574
数字)。
100000!
单独计算(不打印数字)的结果是:
关于c# - BigInteger阶乘的并行计算,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18911262/
我正在尝试计算一个大数,这需要 BigInteger.Pow(),但我需要指数也是 BigInteger 而不是 整数。 即 BigInteger.Pow(BigInteger) 我怎样才能做到这一点
在 Java 中,大多数基本类型都是有符号的(一位用于表示 +/-),因此当我超出类型的限制时,我会得到意想不到的结果,比如负数。 有没有比使用 BigInteger 更好的解决方案,因为 BigIn
如何选择随机元素 α ∈ Z*p? P 是一个随机的 1024 位素数 BigInteger。 这是我找到 BigInteger p 的方法: Random rand = new Random(new
我正在尝试使用 BigInteger 类在 Java 中实现 Fermat、Miller-Rabin 或 AKS 算法。 我想我有Fermat test已实现,但 BigInteger 类不允许将 B
我知道 BigInteger 有一个构造函数,您可以在其中通过传递新 BigInteger 的最大 bitLength 和一个随机参数来生成随机 BigInteger: BigInteger(int
我正在考虑为自己存储公钥的想法。为此,我需要将 BigInteger 转换为某种变量,然后从该值重新创建 BigInteger。 我在 Stackoverflow 中进行了搜索,找到了执行此操作的最佳
目前我正在使用 Long 整数类型。我使用以下方法从/到二进制/数字进行转换: Convert.ToInt64(BinaryString, 2); //Convert binary string of
我有以下代码: public static BigInteger[] Cubes (int m){ Set result = new HashSet(); for (int i = 1
因此,在我的计算机科学课上,我们一直在学习如何使用 Java 编码,并且我遇到了编码本身的第一个局限性。问题是 long 只允许您存储最多 64 位或接近该位的数字。所以我们已经开始用 16 位数字进
你好我想计算 2^(256bit number) 在 java 中,但 biginteger 的 pow 函数只能处理 int。 如何计算更大的数字? 有图书馆吗? 我想计算来自的所有数字 2^0 2
我正在尝试构建一个 BigInteger 数组,但似乎该数组需要由整数本身索引(如果是这样,那对我来说似乎非常愚蠢,但我希望我只是误解了一些东西) .我正在尝试的基本上是以下内容: BigIntege
我在 .Net 项目中使用 BigInteger ( link ) 的单声道实现在 Java 中我使用 java.math.BigInteger。 相同的代码在 Java 中产生不同的结果。 .Net
我正在构建 DSA 算法。但是在将 BigInteger 数字与其他 BigInteger 数字进行排名时遇到了问题。这是我要使用的公式: v = ((g^u1 * y^u2) mod p) mod
我正在尝试用Java实现Schnorr签名算法。我遇到了计算大指数幂(例如 MD5 哈希值)的问题。 有什么方法可以让BigInteger获得BigInteger的权力吗? 我需要计算 (a^x*b^
我正在编写斐波那契程序。 public class ImperativeFibonacci implements Fibonacci { public BigInteger fibonacci(i
我原以为 BigInteger 类中的两个构造函数 BigInteger(String) 和 BigInteger(byte[]) 的行为相似,但事实并非如此。 为什么两个 BigInteger 不相
在 Java 中,要将 String 转换为 BigInteger,您可以使用构造函数 new BigInteger(String),但要将 int/long 转换为工厂函数,您可以使用 BigInt
我正在做一些大整数计算,我需要对一个 BigInteger 求另一个 BigInteger 的幂。 .pow() 方法执行我想要的操作,但将 int 值作为参数。 .modPow 方法采用 BigIn
Java 7 方法的复杂性是什么pow和 isProbablePrime在BigInteger类(class)? 我知道 Rabin 测试的简单实现具有 O(k(log(n))^3) 复杂度,可以通过
.NET 4.0 为任意大的整数提供了 System.Numerics.BigInteger 类型。我需要计算 BigInteger 的平方根(或合理的近似值——例如整数平方根)。这样我就不必重新实现
我是一名优秀的程序员,十分优秀!