在 haskell 中将浮点数舍入为整数
Rounding a float to an int in haskell
欧拉计划第3题说:13195的质因数是5、7、13、29。
600851475143这个数的最大质因数是多少?
我做了一个惰性素数列表,然后我做了一个当它们小于 600851475143 的平方根时,测试每个素数看它是否是一个因数。
primes :: [Integer]
primes = sieve [2..]
where
sieve (p:xs) = p : sieve [x|x <- xs, x `mod` p > 0]
primeFactors :: Integer -> Integer
primeFactors x = last $ filter (\y -> x `mod` y == 0) $ takeWhile (< floor (sqrt x)) $ primes
但是,我收到 (< floor (sqrt x))
错误:
projecteuler.hs:34:70:
No instance for (RealFrac Integer) arising from a use of `floor'
Possible fix: add an instance declaration for (RealFrac Integer)
In the second argument of `(<)', namely `floor (sqrt x)'
In the first argument of `takeWhile', namely `(< floor (sqrt x))'
In the expression: takeWhile (< floor (sqrt x))
projecteuler.hs:34:77:
No instance for (Floating Integer) arising from a use of `sqrt'
Possible fix: add an instance declaration for (Floating Integer)
In the first argument of `floor', namely `(sqrt x)'
In the second argument of `(<)', namely `floor (sqrt x)'
In the first argument of `takeWhile', namely `(< floor (sqrt x))'
这很奇怪: :t floor
给我 (Integral b, RealFrac a) => a -> b
,这意味着这个楼层应该返回一个整数。我如何添加实例声明(或采取任何必要的措施来解决这个问题?)
此外,非常感谢任何有关代码优化的建议:)
编辑:这已经解决了,现在我正在清理它。我已经将所有内容封装在 main 函数中,所以它看起来像这样:
p003primeFactors :: Integer -> [Integer]
p003primeFactors x = filter (\y -> x `mod` y == 0) $ takeWhile (\p -> p^2 <= x) $ primes
where
primes :: [Integer]
primes = sieve [2..]
where
sieve (p:xs) = p : sieve [x|x <- xs, x `mod` p > 0]
这是为这样的函数创建名称空间的最佳方式吗?
实际问题是第二个错误。 (第一个只是结果。)x
是一个 Integer
,因此您不能对其调用 sqrt
,因为它需要一个 Floating
实例。
尝试:
takeWhile (< floor (sqrt (fromIntegral x)))
这会将 x
从整数转换为浮点数,以便 sqrt
可以对其进行运算。
欧拉计划第3题说:13195的质因数是5、7、13、29。 600851475143这个数的最大质因数是多少?
我做了一个惰性素数列表,然后我做了一个当它们小于 600851475143 的平方根时,测试每个素数看它是否是一个因数。
primes :: [Integer]
primes = sieve [2..]
where
sieve (p:xs) = p : sieve [x|x <- xs, x `mod` p > 0]
primeFactors :: Integer -> Integer
primeFactors x = last $ filter (\y -> x `mod` y == 0) $ takeWhile (< floor (sqrt x)) $ primes
但是,我收到 (< floor (sqrt x))
错误:
projecteuler.hs:34:70:
No instance for (RealFrac Integer) arising from a use of `floor'
Possible fix: add an instance declaration for (RealFrac Integer)
In the second argument of `(<)', namely `floor (sqrt x)'
In the first argument of `takeWhile', namely `(< floor (sqrt x))'
In the expression: takeWhile (< floor (sqrt x))
projecteuler.hs:34:77:
No instance for (Floating Integer) arising from a use of `sqrt'
Possible fix: add an instance declaration for (Floating Integer)
In the first argument of `floor', namely `(sqrt x)'
In the second argument of `(<)', namely `floor (sqrt x)'
In the first argument of `takeWhile', namely `(< floor (sqrt x))'
这很奇怪: :t floor
给我 (Integral b, RealFrac a) => a -> b
,这意味着这个楼层应该返回一个整数。我如何添加实例声明(或采取任何必要的措施来解决这个问题?)
此外,非常感谢任何有关代码优化的建议:)
编辑:这已经解决了,现在我正在清理它。我已经将所有内容封装在 main 函数中,所以它看起来像这样:
p003primeFactors :: Integer -> [Integer]
p003primeFactors x = filter (\y -> x `mod` y == 0) $ takeWhile (\p -> p^2 <= x) $ primes
where
primes :: [Integer]
primes = sieve [2..]
where
sieve (p:xs) = p : sieve [x|x <- xs, x `mod` p > 0]
这是为这样的函数创建名称空间的最佳方式吗?
实际问题是第二个错误。 (第一个只是结果。)x
是一个 Integer
,因此您不能对其调用 sqrt
,因为它需要一个 Floating
实例。
尝试:
takeWhile (< floor (sqrt (fromIntegral x)))
这会将 x
从整数转换为浮点数,以便 sqrt
可以对其进行运算。