List 例外情况:除以零

List 例外情况:除以零,list,haskell,List,Haskell,我想找出所有2的幂除以10的列表!它显示异常,即除以零 [2^i | i<-[1..],(factorial(10) `mod` (2^i))==0] [2^i | i Int->Int 最大功率 是p除以n的最大幂!(n的阶乘) 我试着做这个 largest_Power :: Int->Int->Int largest_Power 0 _ =1 largest_Power _ 0 =1 largest_Power n p = floor (logBase (fromIn

我想找出所有2的幂除以10的列表!它显示异常,即除以零

[2^i | i<-[1..],(factorial(10) `mod` (2^i))==0]
[2^i | i Int->Int
最大功率
是p除以n的最大幂!(n的阶乘)

我试着做这个

largest_Power :: Int->Int->Int
largest_Power 0 _ =1  
largest_Power _ 0 =1
largest_Power n p = floor (logBase (fromIntegral p) (fromIntegral (last([p^i | i<-[1..],(factorial(n) `mod` (p^i))==0]))))

factorial::Int->Int
factorial 0=1
factorial 1=1
factorial x=x*factorial(x-1)
最大功率::Int->Int->Int
最大功率0=1
最大功率0=1
最大功率n p=地板(对数基准(from积分p)(from积分)(最后([p^i | iInt
阶乘0=1
阶乘1=1
阶乘x=x*阶乘(x-1)
现在,当我为最大功率10 2运行此程序时,我遇到了一个异常。

Int
出了什么问题? 嗯,
Int
有一个有限的范围-在大多数系统上
-(2^63)
2^63-1

现在,您从
1
(在二进制中也是
1
)开始,然后在二进制中添加零(与乘以2相同)-始终只有一个
1
,后跟
0
s。在某个点上,您隐藏了下限的表示(最高位将表示正值或负值的标记),然后您将添加另一个
0
,该值将溢出
Int
,仅以
0
s结束

您可以很容易地检查这一点:

Prelude> take 64 $ [2^i | i <- [1..]] :: [Int]
[2,4,8,16,32,64,128,
...
,4611686018427387904,-9223372036854775808,0]
将挂起,不会产生任何其他值

原因很简单:对于足够大的
i
2^i>factorial(10)
,并且永远不会再分割它

这就是为什么我建议拔出
mod
的过滤器,并首先将列表限制到这个硬限制:

我不想一遍又一遍地写
factorial10
,所以我首先定义

  • 设m=product[1..10]
    这是
    阶乘10的定义

  • [2^i | i m`mod`n==0)$takeWhile(你对
    阶乘的定义是什么?(就此而言,你根本不清楚为什么要使用
    阶乘,或者你的实际问题是什么。只有1、2、4和8有机会除以10,实际上只有2有机会除以10。)如果你想要2的幂可以被10整除,那么没有一个是;10=2*5,并且没有一个2的幂可以被5整除。我同意@chepner所说的一切,并想补充一点,如果你填写一个阶乘函数并运行它,甚至没有一个被零除的错误……这个错误很可能是因为你使用了
    Int
    instead of
    Integer
    来定义您的
    factorial
    或者您有一个
    Int
    类型的注释,在这里可以得到您的列表
    让m=product[1..10]在过滤器中(\n->m`mod`n==0)$takeWhile(当然,用一点数学很容易:10!=1*2*3*…*10-你想在那里收集所有的基本因子2-它是2,2*2,2*3,2*2,2*5-所以你可以取1到8个2`s,这就是[2^1,…,2^8],这是脚本给你的结果非常感谢你…..你已经完全消除了我所有的疑虑
    
    [2^i | i<-[1..],(factorial(10) `mod` (2^i))==0]
    
    λ> let m = product [1..10] 
       in filter (\n -> m `mod` n == 0) 
          $ takeWhile (<= m) 
         [2^i | i <- [1..]]
    [2,4,8,16,32,64,128,256]
    
    largest_Power :: Int -> Int -> Int
    largest_Power n p = fromIntegral . last $ factorList n p
    
    factorList :: Int -> Int -> [Integer]
    factorList n p =
      filter (\n -> m `mod` n == 0)
      $ takeWhile (<= m) [p'^i | i <- [1..]]
      where m = fromIntegral $ factorial n
            p' = fromIntegral p
    
    factorial :: Int -> Integer
    factorial n = product [1..fromIntegral n]
    
    factorList :: Int -> Int -> [Integer]
    factorList n p =
      map fst
      . filter (\(_,n) -> m `mod` n == 0)
      $ takeWhile ((<= m) . snd) [(i,p'^i) | i <- [1..]]
      where m = fromIntegral $ factorial n
            p' = fromIntegral p
    
    factorCount :: Integral a => a -> a -> a
    factorCount n p =
      let (n',r) = n `divMod` p
      in if r == 0 then 1 + factorCount n' p else 0
    
    largest_Power :: Integral a => a -> a -> a
    largest_Power n p = sum [ factorCount i p | i <- [1..n] ]