【问题标题】:calculating with very big numbers in c在c中计算非常大的数字
【发布时间】:2020-01-27 23:41:16
【问题描述】:

我是编程新手。 我想计算一个在[0,10^24] 范围内的数字的模数。 例如:(12 * 10^22) % 89 我知道我不能使用通常的数据类型(如 long、integer 等)来做到这一点。 我怎样才能做到这一点?有没有办法做到这一点?

提前致谢

【问题讨论】:

  • 评论不用于扩展讨论;这个对话是moved to chat
  • jbond,对于a mod b,以及“范围为 [0,10^24] 的数字”,是否适用于 ab?如果不是,每个a, b 的范围是多少?了解范围限制在 C 中很重要。

标签: c math modulo


【解决方案1】:

显示的表达式可以很容易地通过在每次操作后减少模 89 来计算:

#include <stdio.h>


int main(void)
{
    //  Initialize a product.
    int t = 1;

    //  Calculate 10^22 (modulo 89) by multiplying by 10 (modulo 89) 22 times.
    for (int i = 0; i < 22; ++i)
        t = t * 10 % 89;

    //  Multiply by 12 (modulo 89).
    t = t * 12 % 89;

    //  Show the result.
    printf("%d\n", t);
}

【讨论】:

  • 小优化:i &lt; 11t * 100
  • 更好:对于指数 n,您可以轻松实现 O(log(n)) 解决方案,而不是此处发布的 O(n) 解决方案。标准整数求幂,加上 mod。
  • @TomKarzes:这个课堂练习或竞赛问题的关键概念是简单地减少模 89。对于刚刚学习的学生来说,引入更复杂的算法会使课程复杂化。
【解决方案2】:

正如前面的答案所说,在这种情况下,您可以使用常规整数。

如果您真的需要非常大的整数(就像在许多加密应用程序中一样),周围有几个开源库。查看GNU MP libraryFlint (Fast Library for Number Theory,查看(仅标题!)C++ precision package 或查看Wikipedia's list。它们中的大多数都可以作为您喜欢的 Linux 发行版的软件包提供。

许多语言透明地处理大整数,GNU 的 bc(在您最近的 Linux 机器上)使用它们。

【讨论】:

    【解决方案3】:

    最大的保证 C 数据类型是 uint64_t(参见 stdint.h),最多可容纳 2^64 - 1。我认为最好尽可能保持与标准 C 的一致性,所以我建议一种方法首先简化问题,以免使用比这更广泛的数据类型。为此,让我们借用一个模算术证明:

    xy % z == ((x % z) * (y % z)) % z

    据此,我们可以得出,(12 * 10^22) % 89 == (12 % 89 * 10^11 % 89 * 10^11 %89) % 89 这个新版本当然没有那么漂亮,但它确实使所有因素都很好地适合标准 C 数据类型。计算之前的简化可以用于您范围内的所有数据。

    但是,首先存储要取模的值存在问题。澄清用例是什么可能会得到更适用的答案。例如,值是否存储在字符串中,可能来自用户输入?

    或者,您可以使用某些专为处理非常大的数字而设计的库。我不知道哪个最适合您的目的(我什至不知道您使用的是什么操作系统),但如果您想探索这些选项,只需在网络上搜索“bignum”、“arbitrary-精度”或“无限精度”库应该给你你想要的。

    【讨论】:

    • (12 * 10^22) % 89 == (12 % 89 * 10^11 % 89 * 10^11 %89) % 89 有效,因为10^22 不是素数。然而 OP 正在寻找[0,10^24] 的范围,其中包括许多大素数。 “计算前的简化”是一个好主意,但质数会阻碍这种方法的普遍应用。
    • 我看错了。我把你和 Eric Postpischil 弄糊涂了。我道歉;我还在努力学习这个界面。评论已删除。
    猜你喜欢
    • 2015-02-15
    • 1970-01-01
    • 1970-01-01
    • 2018-08-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多