在 C# 中处理非常大的整数
有谁知道我可以在 C# 中计算非常大的整数的方法吗?
我正在尝试计算数字的阶乘,例如
5! = 5*4*3*2*1 = 120
对于小数字,这不是问题,但尝试计算无符号整数的最大值(4,294,967,295)的阶乘似乎是不可能的。
我已经研究过 BigInteger 类,但它似乎没有做我需要的
任何帮助,将不胜感激
Does anybody know of a way I can calculate very large integers in c#
I am trying to calculate the factorial of numbers e.g.
5! = 5*4*3*2*1 = 120
with small numbers this is not a problem but trying to calculate the factorial of the bigest value of a unsigned int which is 4,294,967,295 it doesn't seem possible.
I have looked into the BigInteger class but it doesn't seem to do what I need
any help would be greatly appreciated
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(9)
要计算
uint.MaxValue
的阶乘,您需要大量存储空间。例如,维基百科文章为 8.2639316883... × 10^5,565,708。 你会疯狂地获取信息。
我强烈怀疑您找不到任何方法在正常的计算机上在合理的时间内计算它。 为什么需要这个值? 斯特林的近似值足够接近吗?
To calculate the factorial of
uint.MaxValue
you'd need a lot of storage.For example, the Wikipedia article as 8.2639316883... × 10^5,565,708. You're going to gain information like crazy.
I strongly suspect you're not going find any way of calculating it on a sane computer in a sane amount of time. Why do you need this value? Would Stirling's approximation be close enough?
首先,值得指出的是,
uint.MaxValue
的阶乘非常大。 我无法找到对其阶乘数量级的良好估计,但它的位表示可能会占用标准 RAM 的很高百分比(如果不是远远超过的话)。BigInteger 类似乎就是您想要的,只要您只想达到大约 1,000,000 左右(非常粗略)。 在那之后,时间和记忆变得非常令人望而却步。 在当前(稳定)版本的 .NET(最高 3.5)中,您必须采用自定义实现。 CodeProject 上的这个似乎评价很高。 如果您碰巧正在为 .NET 4.0 进行开发,Microsoft 团队终于开始包含一个 BCL 的
System.Numerics
命名空间中的BigInteger
类。 与某些 BigInteger 实现不同,.NET 4.0 中现有的实现没有内置阶乘方法(我不确定 CodeProject 的方法),但实现一个应该很简单 - 扩展方法将是一个不错的选择方式。由于您似乎认为您不想使用 BigInteger 类型,因此如果您可以在阅读我的回复后验证这不是您想要的类型,然后准确解释为什么它不适合您的目的,那将会很有帮助。
Firstly, it's worth pointing out that the factorial of
uint.MaxValue
is astronomically large. I'm not able to find a good estimate of the order of magnitude of its factorial, but its bit representation will probably occupy a high percentage of a standard RAM, if not well exceed.A
BigInteger
class seems to be what you want, providing you only want to go up to around 1,000,000 or so (very roughly). After that, time and memory become very prohibitive. In current (stable) versions of .NET, up to 3.5, you have to go with a custom implementation. This one on the CodeProject seems to be highly rated. If you happen to be developing for .NET 4.0, the Microsoft team have finally gotten around to including aBigInteger
class in theSystem.Numerics
namespace of the BCL. Unlike some BigInteger implementations, the one existing in .NET 4.0 doesn't have a built-in factorial method (I'm not sure about the CodeProject one), but it should be trivial to implement one - an extension method would be a nice way.Since you seem to think you don't want to use a BigInteger type, it would be helpful if you could verify that it's not what you want having read my reply, and then explain precisely why it doesn't suit your purposes.
4294967295! = 10^(10^10.597) ~ 10^(40000000000)
即使您会找到任何 C# 的 BigInteger 实现,该值也需要大约 40 Gb 的 RAM 来存储!
PS 好吧,通过优化存储,假设 4 个字节中有 9 个数字,则需要约 18 GB 的 RAM。
4294967295! = 10^(10^10.597) ~ 10^(40000000000)
This value requires about 40 Gb of RAM to store, even if you will find any BigInteger implementation for C#!
P.S. Well, with optimized storing, let's say 9 digits in 4 bytes, it will take ~18 Gb of RAM.
您为什么认为需要计算这些阶乘? 对于进行实际计算来说,实际上没有任何用处。
仅计算(2^32-1)的阶乘结果就占用大量空间,大约16GB。
计算本身当然会花费很多时间。 如果您构建的程序可以将计算过程转移到发明时更快的硬件上,那么您应该能够在有生之年得到结果。
如果您要解决的问题类似于 Euler 问题,请考虑通过消除以下内容找到很多解决方案而是你实际上不必计算就能得到答案。
Why do you think that you need to calculate those factorials? It's not practiacally useful for anything to do the actual calculations.
Just the result of calculating factorial of (2^32-1) would take up a lot of space, approximately 16 GB.
The calculation itself will of course take a lot of time. If you build the program so that you can transfer the calculation process to faster hardware as it is invented, you should be able to get the result within your lifetime.
If it's something like an Euler problem that you are trying to solve, consider that a lot of solutions are found by elliminating what it is that you actually don't have to calculate in order to get the answer.
这里。
最快的一款,直接来自 Factorial Man - Peter Luschny。
Here .
The fastest one, straight from the Factorial Man - Peter Luschny.
您现在可以使用 J# 库中的 BigInteger 类。 这是一篇介绍如何操作的文章。 这使得部署变得更加困难,因为您必须发送 J# 可再发行。 您还可以考虑访问 VS2010 beta 作为 Framework 4.0将有 BigInteger。
You can use the BigInteger class from the J# libraries for now. Here's an article on how. It makes deployment harder because you have to send out the J# redistributable. You can also consider going to VS2010 beta as Framework 4.0 will have BigInteger.
如果您安装了 J# redist,另一种方法是通过添加对 vjslib 程序集的引用来使用 java.math.BigInteger。
In case you have J# redist installed, an alternative way would be using
java.math.BigInteger
by adding a reference to thevjslib
assembly.尝试使用数组来完成此任务。 只要有可用内存空间,您就可以使用尽可能长的整数。 数组的每个成员代表一位十进制数字。 您唯一需要的是实现乘法。
Try to use an array for this task. You could use as long integers as you have free memory space. Every member of array repsesents one decimal digit. The only you need is to implement multipication.
例如,如果您使用组合等阶乘进行计算,则很少需要一直乘以 1(例如 98 * 98 * 97,因为其他所有内容都会抵消)。
If you are doing calculations with factorials like combinations for example you rarely need to multiply all the way down to 1 (eg. 98 * 98 * 97 since everything else cancels out).