【问题标题】:What's wrong with my C code? (Prime factors of a big number)我的 C 代码有什么问题? (大数的质因数)
【发布时间】:2014-01-09 18:45:56
【问题描述】:

你能帮帮我吗?

我是 C 初学者,但我的代码不起作用。

我正在尝试确定 600851475143 的最大素数,当我运行代码时,它什么也不做。但是尝试使用较小的数字会起作用。

long i;

for (i = 600851475143; i > 1; i--)
{
    if (600851475143 % i == 0)
    {
        printf("%d\n", i);
    }
};

【问题讨论】:

  • 什么都不做?还是只需要 非常长的时间 来完成 for 循环?如果我阅读正确,它不会在循环进行到一半之前打印第一行,对吧?
  • Stack Overflow 上有很多类似的问题:google.com/#q=site:stackoverflow.com+c+prime+factor
  • 它是不起作用还是需要很长时间才能完成?这是一个非常大的数字
  • 不要从数字本身开始循环,从该数字的一半开始,它会减少时间但不会改变结果
  • 如果它是一个 32 位处理器,那么这个数字 (600851475143) 是一个溢出,它很可能是负数并且未通过 i > 1 测试。试试long long i;

标签: c for-loop factorization


【解决方案1】:

可能是 32 位系统。数字600851475143 大于 32 位。

代替long i试试:

long long i;

而不是printf("%d\n", i); 试试:

printf("%lld\n", i);

并使用600851475143LL 代替600851475143

【讨论】:

    【解决方案2】:

    首先,打印long 的正确方法不是%d,而是%ld(d = 十进制,ld = 长十进制)。如果 longint 在您的系统上具有不同的大小(这并不罕见),则结果一开始就无法正确打印。

    下一个可能的问题是600851475143 不仅适合32 bit 变量,但long 只能保证至少是32 bit。它可能比这更大,但只保证32 bits。那么您确定long 在您的系统上足够大吗?

    试试

    printf("%zu\n", sizeof(long));
    

    如果它说8,一切都很好,如果它只说4long 是不够的,你需要使用long long 代替(和%lld 用于printf,lld = long长小数)。

    最后但同样重要的是,您知道您的循环需要进行 6000 亿次迭代,不是吗?即使您有一个非常快的系统和非常快的 CPU,这也需要相当长的时间才能完成。因此,您会立即看到600851475143 打印到屏幕上,但您的代码需要很长时间才能终止(或找到另一个除数,以防这不是质数)。

    可选: 你可以写600851475143LL,而不是写600851475143,让编译器知道你希望这个数字是long long类型。似乎 C 2011 标准不再需要这个(如果需要,数字会自动被视为 longlong long),但我知道在 C 2011 之前,一些编译器至少会发出大于数字的警告int(或大于long)。

    【讨论】:

    • 谢谢,代码现在可以工作了,但需要很长时间。所以,你是对的,非常感谢。
    • C 中的整数常量并不总是int。根据 C 2011 6.4.4.1 5,无后缀十进制常量的类型是以下列表中第一个可以表示其值的类型:intlong intlong long int。根据第 6 段,如有必要,它也可以是扩展类型。
    • @user2739184 好了,现在您知道为什么巨大的素数在数据加密中扮演如此重要的角色了。没有“超级快速的方法”来获得某个数字的所有素数,如果一个数字是由两个素数组成的,大小都是 1024 位或更大,猜猜使用类似方法找到这些素数需要多长时间你在上面做了;-)
    • @EricPostpischil 感谢您提供信息。我相应地更改了回复。在 C 2011 之前,对于某些编译器,至少 long long 数字需要 LL,尽管通常这只会导致警告并且编译后的代码仍然正确。
    • 仅供参考 %zusize_t 的正确格式说明符,在这种情况下您不需要 sizeof 的类型转换。
    【解决方案3】:

    您可以从小于或等于大数平方根的最大整数开始循环。然后你可以找到通过循环向下工作的因子对。编写一个单独的函数来检查给定的数字是否是素数。如果该对中较大的因子是素数,则返回它。如果较大的不是素数,则检查较小的是否是素数,如果是则返回。

    【讨论】:

      猜你喜欢
      • 2012-05-20
      • 1970-01-01
      • 2017-05-02
      • 1970-01-01
      • 2015-06-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多