【问题标题】:Haskell prime numbersHaskell素数
【发布时间】:2018-09-06 04:10:18
【问题描述】:

我想生成无限质数,但在某些情况下它会在没有完成无限列表的情况下停止

这是我的尝试:

Primeach :: [Int]

Primeach = [n | n <- [2..] , product [1..n-1] `rem` n == n-1]

【问题讨论】:

  • 请发布您正在使用的实际代码。您提供的代码至少有一个语法错误,不可能产生一个素数,更不用说其中的 34 个了。此外,如果您正在讨论性能,请包括您编译和/或运行代码的方式。
  • 另外,35 不是素数,所以你应该考虑一下这个算法以及为什么它会产生 35...然后修复算法。
  • @ThomasM.DuBuisson 如果您忽略明显的大写错误,它实际上效果很好。
  • @IgnatInsarov 哦,我很清楚这个修复,但它证明提供的代码不是提问者运行的代码。复制和粘贴代码可以为所有潜在的回答者节省大量时间并消除很多困惑。最好不要在没有明确问题的情况下开始回答。
  • @WillemVanOnsem Actually 是正确的(因为Wilson's theorem)。但问题是因为他使用Ints 并且产品溢出超过一定数量(对于 64 位系统,它在 n=22 处溢出)。试图制定一个答案来清楚地解释它。

标签: haskell primes


【解决方案1】:

找不到大于19的素数的问题源于这条线

primeach :: [Int]

这是因为您必须为这些数字计算 product [1..n-1]。这在n &gt;= 22 时会溢出,因为Int(通常)是 64 位系统中的 64 位数字(保证至少有 30 位),在具有 32 位 @987654325 的 32 位系统中@它会在n &gt;= 14溢出。
由于它溢出,您不再采用正确的余数。
例如,对于 64 位有符号整数,我们有 n=23(这是素数):

Prelude> product [1..22]
1124000727777607680000 :: Integer
Prelude> product [1..22] :: Int
-1250660718674968576 :: Int
Prelude> product [1..22] `rem` 23
22 :: Integer
Prelude> product [1..22] `rem` 23 :: Int
-22 :: Int

如您所见,由于溢出,这不再有效。 另一个例子是n=29,它也是素数:

Prelude> product [1..28]
304888344611713860501504000000 :: Integer
Prelude> product [1..28] :: Int
-5968160532966932480 :: Int
Prelude> product [1..28] `rem` 29
28 :: Integer
Prelude> product [1..28] `rem` 29 :: Int
-27 :: Int

所以这表明它甚至不是一个简单的符号翻转。

你有两个选择:

  • 如果你想使用这个算法,切换到Integers(即使只是为了product计算),那些永远不会溢出:

    primeach :: [Int]
    primeach = [fromInteger n | n <- [2..] , product [1..n-1] `rem` n == n-1]
    
  • 使用不同的算法,或考虑使用现有的素数包。

【讨论】:

    猜你喜欢
    • 2011-05-31
    • 2019-09-30
    • 1970-01-01
    • 1970-01-01
    • 2012-08-06
    • 1970-01-01
    • 2014-07-11
    • 1970-01-01
    • 2014-11-10
    相关资源
    最近更新 更多