【问题标题】:Raising large number to large power and mod it by a large number?将大数提高到大功率并对其进行大量修改?
【发布时间】:2014-11-26 16:03:20
【问题描述】:

我被一个可能很简单的问题困住了。 我得到了 3 个大数(A、B、C),所有整数,我需要执行以下操作:将 A 幂到 B 并以 C 取模,然后检查结果是否等于 1。这是我的代码:

double power = fmod((pow((double)A,(double)B)),(double)C);
    if (power != 1){
        printf("Something!\n");
    }

而且它不起作用(我尝试了小数字,比如 17 由 28 驱动并由 29 模块化)。有什么建议吗?

【问题讨论】:

标签: c bignum


【解决方案1】:

试试这个(为了避免算术溢出):

unsigned long long power = 1;
A %= C;
while (B > 0)
{
    power = (power * A) % C;
    B--;
}

您可以通过以下方式进一步提高运行时性能:

unsigned long long power = 1;
A %= C;
while (B > 0)
{
    if (B & 1)
        power = (power * A) % C;
    B >>= 1;
    A = (A * A) % C;
}

【讨论】:

  • 如果 A、B 和 C 是 int 且 unsigned long long 是 int 的两倍,则此方法有效。但我们不知道这些数字有多大,它们是什么类型
  • @LưuVĩnhPhúc:正确,但这个问题没有暗示输入参数的最大值(ABC),所以我尽力使用给定的信息。 ..
  • 是的,但实际上它是之前许多其他问题的答案,这只是重复
  • @LưuVĩnhPhúc 实际上它们可能高达数百万甚至数十亿,因为我尝试构建 Lucas 素性测试(不是 Lucas-Lehmer)的实现,其中一项操作是为 0 和N乘N-1并调制结果。
【解决方案2】:

Double 的最小和最大尺寸分别为 -1.7*10^308 和 1.7*10^308。如果你需要更大的,你可以试试 long long。

不确定您为什么使用 fmod。但这应该做你想做的。

double power = ( pow(A, B) ) % C;
if (power != 1){
        printf("Something!\n");
    }

【讨论】:

  • % 不适用于整数类型。此外,这是不正确的,因为 double 只准确到前几位
  • 使用他的 17、28、29 示例在我的计算机上工作得很好。根据 WolfRamAlpha,我得到的那个例子是正确的 1。
  • 纯靠运气。此外,如果我将 pow 的结果转换为 unsigned long long,它会在我的计算机上返回 12,如果我将其转换为 unsigned int,它会返回 0。 17^28 需要大约 114.449 位,并且绝对 double 在当前机器中不能具有那么大的精度
【解决方案3】:

试试这个方法

double a,b,c;

a = 1124124124254234;
b = 1124124124254234 * 5;
c = 1124124124254234 * 2;

double power = pow(a,b); 

double mod = fmod(power, c);

if (mod != 1){
    printf("Something!\n");
}

【讨论】:

  • 同上,% 不适用于整数类型,由于 double 的精度有限,结果不正确
  • @LưuVĩnhPhúc % 仅适用于整数,不适用于双精度。
猜你喜欢
  • 2017-09-22
  • 1970-01-01
  • 2015-03-31
  • 2012-04-24
  • 2018-11-24
  • 2019-06-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多