手动修改数字的快速方法
我需要能够计算 (a^b) % c 对于非常大的 a 和 b 值(它们分别推动限制,当您尝试计算 a^b 时会导致溢出错误)。 对于足够小的数字,使用恒等式 (a^b)%c = (a%c)^b%c 是可行的,但如果 c 太大,这并没有什么帮助。 我编写了一个循环来手动执行 mod 操作,一次一个:
private static long no_Overflow_Mod(ulong num_base, ulong num_exponent, ulong mod)
{
long answer = 1;
for (int x = 0; x < num_exponent; x++)
{
answer = (answer * num_base) % mod;
}
return answer;
}
但这需要很长时间。 有没有简单快速的方法来执行此操作,而无需实际使用 a 的 b 次方 AND 且无需使用耗时的循环? 如果一切都失败了,我可以创建一个 bool 数组来表示一个巨大的数据类型,并弄清楚如何使用按位运算符来做到这一点,但必须有更好的方法。
I need to be able to calculate (a^b) % c for very large values of a and b (which individually are pushing limit and which cause overflow errors when you try to calculate a^b). For small enough numbers, using the identity (a^b)%c = (a%c)^b%c works, but if c is too large this doesn't really help. I wrote a loop to do the mod operation manually, one a at a time:
private static long no_Overflow_Mod(ulong num_base, ulong num_exponent, ulong mod)
{
long answer = 1;
for (int x = 0; x < num_exponent; x++)
{
answer = (answer * num_base) % mod;
}
return answer;
}
but this takes a very long time. Is there any simple and fast way to do this operation without actually having to take a to the power of b AND without using time-consuming loops? If all else fails, I can make a bool array to represent a huge data type and figure out how to do this with bitwise operators, but there has to be a better way.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(11)
我猜您正在寻找:http://en.wikipedia.org/wiki/Montgomery_reduction
或者基于模幂的更简单的方法(来自维基百科)
I guess you are looking for : http://en.wikipedia.org/wiki/Montgomery_reduction
or the simpler way based on Modular Exponentiation (from wikipedia)
快速模幂(我认为这就是它的名字)可能会起作用。
现在,我不知道你将如何处理数据类型。 只要你的数据类型可以支持c^2,我想你就可以了。
如果使用字符串,只需创建加法、减法和乘法的字符串版本(不太难)。 这个方法应该足够快。 (并且您可以通过 mod c 开始步骤 1,以便 a 永远不会大于 c)。
编辑:哦,看,模幂 上的 wiki 页面。
Fast Modular Exponentiation (I think that's what it's called) might work.
Now, how you're going to do that with data types, I don't know. As long as your datatype can support c^2, i think you'll be fine.
If using strings, just create string versions of add, subtract, and multiply (not too hard). This method should be quick enough doing that. (and you can start step 1 by a mod c so that a is never greater than c).
EDIT: Oh look, a wiki page on Modular Exponentiation.
这是 java 中的快速模幂运算(在早期答案之一中建议)的示例。 将其转换为 C# 应该不会太难
http:// www.math.umn.edu/~garrett/crypto/a01/FastPow.html
和来源...
http://www.math.umn.edu/~garrett/crypto/a01/FastPow.java
Here's an example of Fast Modular Exponentiation (suggested in one of the earlier answers) in java. Shouldn't be too hard to convert that to C#
http://www.math.umn.edu/~garrett/crypto/a01/FastPow.html
and the source...
http://www.math.umn.edu/~garrett/crypto/a01/FastPow.java
Python 有 pow(a,b,c) ,它返回 (a**b)%c (只是更快),所以必须有一些聪明的方法来做到这一点。 也许他们只是做你提到的身份。
Python has pow(a,b,c) which returns (a**b)%c (only faster), so there must be some clever way to do this. Maybe they just do the identity you mentioned.
我建议检查 Decimal 文档并查看它是否满足您的要求,因为它是内置类型并且可以使用 mod 运算符。 如果没有,那么您将需要一个任意精度的库,例如 java 的 Bignum。
I'd recommend checking over the Decimal documentation and seeing if it meets your requirements since it is a built in type and can use the mod operator. If not then you're going to need an arbitrary precision library like java's Bignum.
您可以尝试将“a”分解为足够小的数字。
如果“a”的因子是“x”、“y”和“z”,则
a^b = (x^b)(y^b)(z^b)。
然后你就可以使用你的身份:(a^b)%c = (a%c)^b%c
You can try factoring 'a' into sufficiently small numbers.
If the factors of 'a' are 'x', 'y', and 'z', then
a^b = (x^b)(y^b)(z^b).
Then you can use your identity: (a^b)%c = (a%c)^b%c
在我看来,功率和模组之间似乎存在某种关系。 幂只是重复的乘法,而模与除法有关。 我们知道乘法和除法是相反的,所以通过这种联系我会假设幂和模之间存在相关性。
例如,取 5 的幂:
该模式很明显,对于 b 的所有值,5 ^ b % 4 = 1。
在这种情况下还不太清楚:
但仍然存在一种模式。
如果你能计算出模式背后的数学原理,那么如果你能在不计算实际功率的情况下计算出 mod 的值,我不会感到惊讶。
It seems to me like there's some kind of relation between power and mod. Power is just repeated multiplication and mod is related to division. We know that multiplication and division are inverses, so through that connection I would assume there's a correlation between power and mod.
For example, take powers of 5:
The pattern is clear that 5 ^ b % 4 = 1 for all values of b.
It's less clear in this situation:
But there's still a pattern.
If you could work out the math behind the patterns, I wouldn't be surprised if you could figure out the value of the mod without doing the actual power.
您可以尝试以下操作:
C#:对非常大的数字执行取模 (mod) 运算 (> Int64.MaxValue)
http://www.del337ed.com/blog/index.php/2009/02/04/c-doing-a-modulus-mod-operation-on-a-very-large -number-int64maxvalue/
You could try this:
C#: Doing a modulus (mod) operation on a very large number (> Int64.MaxValue)
http://www.del337ed.com/blog/index.php/2009/02/04/c-doing-a-modulus-mod-operation-on-a-very-large-number-int64maxvalue/
如果没有编写自己的快速模幂,我能想到的最简单的想法就是使用 F# BigInt 类型:
Microsoft.FSharp.Math.Types.BigInt
,它支持任意大规模的运算 - 包括求幂和模运算。它是一种内置类型,将成为下一版本的完整 .NET 框架的一部分。 您不需要使用 F# 来使用 BitInt - 您可以直接在 C# 中使用它。
Short of writing your own fast modular exponentiation, the simplest idea I can come up with, is to use the F# BigInt type:
Microsoft.FSharp.Math.Types.BigInt
which supports operations with arbitrarily large scale - including exponentiation and modular arithmetic.It's a built-in type that will be part of the full .NET framework with the next release. You don't need to use F# to use BitInt - you can make use of it directly in C#.
你能因式分解 a、b 或 c 吗? C 是否有已知范围?
这些是 32 位整数! 去检查这个 网站
例如,这里是如何获取 mod n%d where d 1>>s (1,2,4,8,...)
n%d 有代码,其中 d 为 1>>s - 1 (1, 3, 7, 15, 31 ,...)
这只有在 c 很小的情况下才会真正有帮助,就像你说的那样。
Can you factor a, b, or c? Does C have a known range?
These are 32 bit integers! Go check this site
For instance, here is how you get the mod of n%d where d 1>>s (1,2,4,8,...)
There is code for n%d where d is 1>>s - 1 (1, 3, 7, 15, 31, ...)
This is only going to really help if c is small though, like you said.
看起来像是密码学的作业。
提示:查看费马小定理。
Looks like homework in cryptography.
Hint: check out Fermat's little theorem.